password_verify() logging in all the time - php

Using codeigniter hashed my password with BCRYPT, seems that everytime I login I redirect to the success page. So I am figuring password verify is not working, even if I enter the incorrect login it still redirects, does not throw the form_validation errors either.
I used the documentation to set it up along with the guides on SO. Will eventually go to Ion Auth but want to know how to fix this. As I am still learning code igniter mvc.
Model
class user_model extends CI_Model{
public function register($encrypt_pass){
$data = array(
'name'=> $this->input->post('name'),
'email'=> $this->input->post('email'),
'username'=> $this->input->post('username'),
'password'=>password_hash($encrypt_pass,PASSWORD_BCRYPT)
);
return $this->db->insert('customers',$data);
}
public function login($username,$password){
//validate the inputs from form
$this->db->where('username',$username);
$query = $this->db->get('customers'); //customers is the table
$result = $query->row_array();
if(!empty($result) && password_verify($password, $result['password'])){
return $result;
}
else{
return "false";
}
}
}
Controller
public function login()
{
$this->form_validation->set_rules('username','Username','required');
$this->form_validation->set_rules('password','Password','required');
if($this->form_validation->run()=== FALSE){
$this->load->view('templates/header');
$this->load->view('users/login',$data);
$this->load->view('templates/footer');
}
else {
//Getting username
$username = $this->input->post('Username');
//Getting and ecrypting password
$password = $this->input->post('Password');//password hashed
$user_id = $this->user_model->login($result);
//checking for user/pass correct will set session if so
if($user_id){
$this->session->set_flashdata('user_loggedin','You are now logged in');
redirect('posts');
}
// If combo is incorrect will redirect
else{
$this->session->set_flashdata('user_loggedin','Login Failed, Please Try
Again');
redirect('users/login');
}
}
}
}

Here is a simple working login code, there are many ways how to do it, it's just an example.
ON YOUR MODEL
Create a function that will check/get the username's password.
public function _getUserPassword($user_name){
$data = array();
$this->db->select('PASSWORD');
$this->db->from('tbl_user');
$this->db->where('USER_NAME', $user_name);
$query = $this->db->get();
if($query->num_rows() > 0){
foreach($query->result_array() as $field_name => $field_value){
$data = $field_value;
}
return $data;
}
else{
return false;
}
}
I've seen your's just selecting it.
We need to use that _getUserPassword function on we call it verify function
function verify($username, $password){
$data = array();
$userNameExists = $this->_getUserPassword($username);
if(password_verify($password, $userNameExists['PASSWORD'])){
$this->db->select('*');
$this->db->from('tbl_user AS user');
$this->db->where('USER_NAME', $username);
$query = $this->db->get();
if($query->num_rows() > 0){
foreach($query->result_array() as $field_name => $field_value){
$data = $field_value;
}
return $data;
}
else{
return false;
}
}
else{
return false;
}
}
So if the verification is success it will return the data to your controller, Let's use your controller.
Let's assume that you changed the models
ON YOUR CONTROLLER
public function login()
{
$this->form_validation->set_rules('username','Username','required');
$this->form_validation->set_rules('password','Password','required');
if($this->form_validation->run()=== FALSE){
$this->load->view('templates/header');
$this->load->view('users/login',$data);
$this->load->view('templates/footer');
}else {
//Getting username
$username = $this->input->post('Username');
//Getting and ecrypting password
$password = $this->input->post('Password');
$user_id = $this->user_model->verify($username,$password);
//checking for user/pass correct will set session if so
if($user_id){
$this->session->set_userdata('user_loggedin','You are now logged in');
redirect('posts');
}else{
//DO NOT SET USER DATA SESSION HERE UNLESS IT WILL AUTOMATICALLY LOGGED IN.
redirect('users/login');
}
}
}
Hope this helps!

where you are checking that password is matching or not.
try this in your controller.after user check.
if($user>0){
if (password_verify($this->input->post('Password'), $user_id['password'])) {
//success message
}
else{
//error message.password is invalid
}

Related

Login in CodeIgniter with password_verify

I'm trying to achieve to login implementation in CodeIgniter, I'm hashing password while registration like password_hash($this->input->post('password'),PASSWORD_DEFAULT) in my Controller and in the same Controller I'm trying to write a login method which is as followed :
public function loginValidation() {
$this->form_validation->set_rules('email', 'Email', 'trim|required');
$this->form_validation->set_rules('password', 'Password', 'trim|required');
if ($this->form_validation->run()) {
// true
$email = $this->input->post('email');
$password = $this->input->post('password');
// User Model Loaded in constructor
if ($this->user->canLogin($email, $password)) {
$session_data = array('email' => $email );
$this->session->set_userdata($session_data);
redirect('profile/personal','Refresh');
} else {
$this->session->set_flashdata('error', 'Invalid Username or Password');
//redirect('login','Refresh');
}
} else {
// try again to login
//redirect('login','Refresh');
}
}
My user Model function is
public function canLogin($email, $password) {
$this->db->where('email',$email);
$this->db->where('password',$password);
$query = $this->db->get($this->tableName);
if ($query->num_rows() > 0) {
return true;
} else {
return false;
}
}
I know I have to password_verify($string,$hash) at some point but I'm unable to figure out.
How do I validate the password against email and redirect to the desired view i.e. personal/profile and I'm making request via AJAX call.
What you need to do is fetch the record from the DB where only the email matches (assuming it is the Unique key). Then you compare the returned value using password_verify().
This is very rough and untested, but should give you an idea:
public function canLogin($email, $password) {
$this->db->where('email',$email);
// $this->db->where('password',$password);
$query = $this->db->get($this->tableName);
$row = $query->row();
return $row ? password_verify($password, $row->password) : false;
}

change password in codeigniter with logged in users throws error

I want to change the password for logged in users,but it always give me an error:[Message: Trying to get property 'password' of non-object] in the controller. How to solve this error???
Please help,Thanks much!
This is my controller:
if($this->form_validation->run()){
$cur_password = md5($this->input->post('cpassword')); // md5-encrypt the password
$new_password = md5($this->input->post('npassword'));
$conf_password = md5($this->input->post('copassword'));
//$this->load->model('queries');
$this->load->library('session');
$user_id = $this->session->userdata('user_id');//multiple users id login
$passwd = $this->queries->getCurPassword($user_id);
!ERROR FOUND HERE!->if($passwd->password == $cur_password){
if($new_password == $conf_password){
if($this->queries->updatePassword($new_password,$user_id)){
echo 'Password Updated Successfully!';
echo '<br/><label>Back to homepage</label><br/>';
}else{
echo 'Failed To Update Password!!';
}
}else{
echo 'New Password and Confirm Password is not matching!!';
}
}else{
echo 'Sorry! Current Password is not matching!!';
}
}else{
echo validation_errors();
}
This is my model:
<?php
class Queries extends CI_Model{
function login() {
$query = $this->db->select('*')
->from('users')
->where('id');
return $query->row();
}
function index() {
$userid = $this->login()->id; //id of the user which is currently logged IN
$this->session->set_userdata('user_id', $user_id);
}
public function getCurPassword($user_id){
$query = $this->db->where(['id'=>$user_id])
->get('users');
if($query->num_rows() > 0 ){
return $query->row();
}
}
public function updatePassword($new_password,$user_id){
$data = array(
//'password' => md5($this->input->post("$new_password"))
'password' => ($new_password)
//'password'=> password_hash(["$new_password"],PASSWORD_BCRYPT)
);
return $this->db->where('id',$user_id)
->update('users',$data);
}
}
Thanks!
You have error in your syntax error says that you are trying to get property of non-object means $passwd may be an array
if($passwd['password'] == $cur_password)
And in case you have null user_id
Place these two lines in your controller function above if($this->form_validation->run()){ line
$userid = $this->queries->login()->id; //id of the user which is currently logged IN
$this->session->set_userdata('user_id', $userid);
and in your login function in model
function login() {
$query = $this->db->select('*')
->from('users')
->where('username',$this->session->userdata('username'));
return $query->row();
}
Hope it helps!
This happens when the user_id not found.
Notice that the getCurPassword function will return the user if found (when checking if num_rows > 0) but if didn't found it returns NULL.
When this happens the $passwd var is null so you cann't access $passwd->password.
You can solve it by changing the if statement to:
if($passwd && $passwd->password == $cur_password){
Edited Try to retrieve your user name as and then call with it the getCurPassword function:
$user_name = $this->session->userdata('username');
$passwd = $this->queries->getCurPassword($user_name );
And in the controller change getCurPassword function as:
public function getCurPassword($user_name){
$query = $this->db->select('*')
->from('users')
->where('username', $user_name);
if($query->num_rows() > 0 ){
return $query->row();
}
}
Notice that I assume you have "username" column in your DB

Login verification not working in CodeIgniter

Hello,
so I built a login system in CodeIgniter in which 3 verification's steps are/should be met with the database before being allowed to access to the specific pages.
The three steps values are: active, is_member and is_admin
This is the code that I made in my Users controller:
public function login(){
// Prohibit access if already logged in
$this->User_model->session_comprobate_member();
$this->form_validation->set_rules('username','Username','trim|required|min_length[4]');
$this->form_validation->set_rules('password','Password','trim|required|min_length[4]');
if ($this->form_validation->run() == FALSE){
//Load View Into Template
$this->template->load('public','login','users/login');
} else {
// Get Post Data from Database
$username = $this->input->post('username');
$password = $this->input->post('password');
$enc_password = md5($password);
$data_user = $this->User_model->login($username, $enc_password);
if($data_user == true){
$user_id = $this->User_model->get_userid($username);
$users = $this->User_model->get_username($user_id);
if($users->active == 0){
// Create error
$this->session->set_flashdata('error', 'This account is banned or inactive');
// Redirect to page
redirect('dashboard/login');
}
if($users->is_admin == 0){
// Create error
$this->session->set_flashdata('error', 'You do not have permission to view this page');
// Redirect to page
redirect('dashboard/login');
}
if($users->is_member == 0){
// Create error
$this->session->set_flashdata('error', 'This account does not exists. Please try again.');
// Redirect to page
redirect('dashboard/login');
} else {
$sess_data = array(
'user_id' => $user_id,
'username' => $username,
'occupation' => 'occupation',
'is_member' => true,
'is_admin' => true,
'active' => true
);
// Set Session Data
$this->session->set_userdata($sess_data);
// Create Message
$this->session->set_flashdata('success', 'You are logged in');
// Redirect to pages
redirect('dashboard');
}
} else {
// Create Error
$this->session->set_flashdata('error', 'Invalid Login');
// Redirect to pages
redirect('dashboard/login');
}
}
}
Each of these values are set to TRUE(1) or FALSE(0) depending on the user account.
I have an account with the tree values equal to 1 so it should allow me to access; here is a picture:
What I want is to be allowed to access after the login verification has met the three values
but for some reason even after having the user with all set to TRUE if just keeps throwing me the first error that I created:
$this->session->set_flashdata('error', 'This account is banned or inactive');
Any idea how to fix it?
Thanks.
Here is my model:
public function get($id)
{
$this->db->where('id', $id);
$query = $this->db->get($this->table);
return $query->row();
}
public function login($username, $password)
{
$this->db->select('*');
$this->db->from($this->table);
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->limit(1);
$query = $this->db->get();
if ($query->num_rows() == 1) {
return $query->row()->id;
} else {
return false;
}
}
//I need to work on these two
public function get_username($users) {
$this->db->select('id');
$this->db->from($this->table);
$this->db->where('username', $users);
return $this->db->get()->row;
}
public function get_userid($user_id) {
$this->db->select('id');
$this->db->from($this->table);
$this->db->where('id', $user_id);
return $this->db->get()->row();
}
///
//Check if admin
public function is_admin($id) {
$this->db->select('is_admin');
$this->db->from($this->table);
$this->db->where('id', $id);
$is_admin = $this->db->get()->row('is_admin');
if ($is_admin == 0) {
redirect('/');
} else {
redirect('admin');
}
}
//Check if member
public function is_member($id) {
$this->db->select('is_member');
$this->db->from($this->table);
$this->db->where('id', $id);
$is_member = $this->db->get()->row('is_member');
if ($is_member == 0) {
redirect('/');
} else {
redirect('dashboard/login');
}
}
//Check if active
public function is_active($id) {
$this->db->select('active');
$this->db->from($this->table);
$this->db->where('id', $id);
$is_active = $this->db->get()->row('active');
if ($is_active == 0) {
redirect('/');
} else {
redirect('dashboard/login');
}
}
Again thanks for the help.
assuming username is unique column in table:
Controller
// user login
if($data_user == true) {
// $username from $this->input->post('username');
// call model function
$user = $this->User_model->get_username($username);
// is active user ?
if($user['active'] == 0) {
// Create error
$this->session->set_flashdata('error', 'This account is banned or inactive');
// Redirect to page
redirect('dashboard/login');
}
// is admin ?
if($user['is_admin'] == 0) {
// Create error
$this->session->set_flashdata('error', 'You do not have permission to view this page');
// Redirect to page
redirect('dashboard/login');
}
// is member ?
if($user['is_member'] == 0) {
// Create error
$this->session->set_flashdata('error', 'This account does not exists. Please try again.');
// Redirect to page
redirect('dashboard/login');
} else {
$sess_data = array(
'user_id' => $user['id'],
'username' => $user['username'],
'occupation' => 'occupation',
'is_member' => true,
'is_admin' => true,
'active' => true
);
// Set Session Data
$this->session->set_userdata($sess_data);
// Create Message
$this->session->set_flashdata('success', 'You are logged in');
// Redirect to pages
redirect('dashboard');
}
} else {
// Create Error
$this->session->set_flashdata('error', 'Invalid Login');
// Redirect to pages
redirect('dashboard/login');
}
this model for get_username()
public function get_username($username) {
// select field we needed
$this->db->select('id', 'username', active, is_admin, is_member);
$this->db->from($this->table);
$this->db->where('username', $username);
$this->db->limit(1);
$query = $this->db->get();
// check is $query have a data ?
if ($query->num_rows() > 0) {
// return data
return $query->row_array();
} else {
// redirect login, because no data with that username
redirect('dashboard/login');
}
}
In your get_username() in model you are selecting only id and in controller you are checking values in active column. Add active column in get_username() selection.

codeigniter login after email verified

I am trying to make sure user can login after confirming their email verification in which STATUS in the database changes from 0 to 1. how do I log users in based on the change of status in the database. Thanks in advance
MODEL:
public function login($username, $password){
//validation
$this->db->where('username', $username);
$this->db->where('password', $password);
$result = $this->db->get('users');
if($result->num_rows() == 1){
return $result->row(0)->id;
} else {
return FALSE;
}
}
CONTROLLER:
public function login(){
$data['title'] = 'Login';
$this->form_validation-> set_rules('username', 'Username', 'required');
$this->form_validation-> set_rules('password', 'Password', 'required');
if($this->form_validation->run() === FALSE){
$this->load->view('templates/header');
$this->load->view('users/login', $data);
$this->load->view('templates/footer');
} else {
// fetching user
$username = $this->input->post('username');
//password
$password = ($this->input->post('password'));
//login user
$user_id = $this->user_model->login($username, $password);
if($user_id){
//creating session
$user_data = array(
'user_id' => $user_id,
'username' => $username,
'logged_in' => TRUE,
);
$this->session->set_userdata($user_data);
// Set message to be sent
$this->session->set_flashdata('user_login', 'Welcome');
redirect('posts');
} else {
// Set message to be sent
$this->session->set_flashdata('login_fail', 'Login Failed');
redirect('users/login');
}
}
}
You just need to verify that the user who's trying to login is verified (if am getting your query right).
for this you can just add another where statement in your query builder while checking username and password. So your model will be like
public function login($username, $password){
//validation
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->where('status', '1');
$result = $this->db->get('users');
if($result->num_rows() == 1){
return $result->row(0)->id;
} else {
return FALSE;
}
}
So now even if user have submitted correct login details but haven't verified his account yet, he'll be unable to login.
If you are asking about how to check that user is verified or not then this should be your model code:
public function login($username, $password){
$query = $this->db
->select('your_column')
->where(['user_email' => $user_name, 'user_password' => $user_password])
->where('user_verification_status','1')
->get('users');
if ($query->num_rows() == 1) {
$result = $query->row_array();
return $result;
} else {
return FALSE;
}
}
OR if you want to verify user after registration then you should follow this step:
When Someone Register in your system and when you are saving that user data in your registration table at that time you should use entered email and send the verified link on user email.
In that verification link you have structured it as when user click on it it came to your verification page and at that time you should change the status of user and show message that user is verified and now you can login into the system.
And as the model code given in the answer you should check that user have verified or not.
Please let me know if you need more detail regarding the user verification.
Considering you have the verification system ready and you're changing the status column in db from 0 to 1.
Using the code below, you will be able to perform login based on that requirement by informing the user in case he isn't verified.
Model (return with proper errors):
public function login($username, $password){
$this->db->where('username', $username);
$this->db->where('password', $password);
$result = $this->db->get('users');
if($result->num_rows() == 1){
$user=$result->row_array();
if($user['status']==1){ // user is verified
$response['error']="false";
$response['user']=$user['id'];
}
else{ // not verified
$response['error']="true";
$response['error_msg']="Please verify your email first!";
}
}
else { // credentials mismatch
$response['error']="true";
$response['error_msg']="Invalid username or password";
}
return $response;
}
Controller (use returned array from model)
//login user
$login = $this->user_model->login($username, $password);
if($login['error']){ // login failed
$this->session->set_flashdata('login_fail', $login['error']);
redirect('users/login');
}
else{ // success
$user=$login['user'];
// do whatever you want after successful login
}

Login form not validating

I am creating a login form but it does not do the validation rightly against the value in the database. when I put in the wrong password it still redirects me to the page that needs login access
CONTROLLER
public function login() {
$this->form_validation->set_rules('username', 'Username', 'trim|required|alpha_numeric|min_length[6]|max_length[12]|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|alpha_numeric|min_length[6]|max_length[6]|xss_clean');
if ($this->form_validation->run() == FALSE) {
// return main page if submitted form is invalid.
$this->load->view('abt_login');
} else {
$this->load->model('abt_db');
$q = $this->abt_db->check_login();
if($q)
{
$data = array(
'email' => $this->input->post('email'),
'password' => $this->input->post('password'),
);
$this->session->set_userdata($data);
redirect('index.php/abovetheblues/abt-abovetheblues');
}
else
{
redirect('index.php/abovetheblues/abt_selfhelp');
}
}
}
MODEL
function check_login() {
$this->load->database();
$this->db->where('email', $this->input->post('email'));
$this->db->where('password', $this->input->post('password'));
$q = $this->db->get('user');
if ($q->num_rows == 1) {
return true;
}
}
num_rows is a function and you not call the function
Try to change this:
if ($q->num_rows == 1) {
return true;
}
to this:
if ($q->num_rows() == 1) {
return true;
}
Consider passing the two variables to the function instead of trying to grab them from the input class:
Controller:
$this->load->model('abt_db');
$q = $this->abt_db->check_login($this->input->post('email'), $this->input->post('password'));
Model:
function check_login($email, $password) {
$this->load->database();
$this->db->where('email', $email);
$this->db->where('password', $password); ## VERY UNSECURE - SEE BELOW
$q = $this->db->get('user');
if ($q->num_rows() == 1) { ## as seen in the previous answer
return true;
}
return false; ## You NEED to have this.
}
PLEASE NOTE:
You are checking the password directly with the database in plaintext. This is a terrible idea and will lead to your application getting compromised.
I strongly recommend you read this excellent primer on password security:
Salting Password Hashing

Categories