password hashing cannot login codeigniter

Viewed 352

I have this helper to encrpyt my password

<?php 
defined('BASEPATH') OR exit('No direct script access allowed');

/*
 * This function used to generate the hashed password
 * @param {string} $plainPassword : This is plain text password
 */
if(!function_exists('getHashedPassword'))
{
    function getHashedPassword($plainPassword)
    {
        return password_hash($plainPassword, PASSWORD_DEFAULT);
    }
}
/**
 * This function used to generate the hashed password
 * @param {string} $plainPassword : This is plain text password
 * @param {string} $hashedPassword : This is hashed password
 */
if(!function_exists('verifyHashedPassword'))
{
    function verifyHashedPassword($plainPassword, $hashedPassword)
    {
        return password_verify($plainPassword, $hashedPassword) ? true : false;
    }
}

?>

Now I don't have any problem storing the hashed password to my database and I am doing it like this

on my model

function saveAccount($userinfo)
{
    $data = array(
       'username' => $this->input->post('username'),
       'password' => $userinfo,
       'type' => $this->input->post('accountType')
    );

    return $this->db->insert('users', $data);

}

and on my controller

$userInfo = getHashedPassword($this->input->post('password'));
$this->employee->saveAccount($userInfo);

Now this registration process is currently working and I don't have any problem storing it on my database now my problem is that whenever I tried to login to the user i currently registered for like example . username : admin5 password : admin5 (which is encrypted on my database)

on my controller for logging in

$username = $this->input->post('username');  
$password = $this->input->post('password');
$user_data = $this->employee->can_login($username,$password);

and on my model

function can_login($username, $password)
    {

        $this->db->where('username', $username);
        $this->db->where('password', $password);
        $query = $this->db->get('users');
        $user = $query->result();

        verifyHashedPassword($password, $user[0]->password);
        if($query->num_rows() > 0)
        {
            return $query->row_array();
        }
        else
        {
            return false;
        }
    }

what do you think could be the problem ?

1 Answers

You are making this a tad overly complex - the actions of the functions you are using makes little sense to put inside a function - its a simple one-liner. And password_verify() already returns a boolean true/false, so you don't need to use a ternary operator either.

Your insert can be more clear and explicit by doing the following (and removing your getHashedPassword() function),

function saveAccount()
{
    $data = array(
       'username' => $this->input->post('username'),
       'password' => password_hash($this->input->post('password'), PASSWORD_DEFAULT),
       'type' => $this->input->post('accountType')
    );

    return $this->db->insert('users', $data);
}

Then in your can_login() function, you cannot query the password in a WHERE clause. By doing that, you will never get a result back (as the hash isn't comparable through a comparison operator). You need to fetch it, and then compare the retrieved hash by using password_verify(). Calling your verifyHashedPassword() without checking the result won't magically check anything. Now, you can also remove your verifyHashedPassword() function.

function can_login($username, $password) {
    $this->db->where('username', $username);
    $query = $this->db->get('users');
    $user = $query->result();

    if ($query->num_rows() > 0 && password_verify($password, $user[0]->password)) {
        return $query->row_array();
    } else {
        return false;
    }
}

Your password column should be of at least 60 characters length, although to accommodate future changes, it can be longer (for example 255 characters long).

Related