password_hash, password_verify, MySQL misunderstanding?

谁都会走 提交于 2019-11-27 05:30:27

You can't hash the input and then query against that in the database, as the hash will use a different random salt each time. So you could hash the same password a thousand times and get 1000 different results.

You need to simply just query the DB for the record related to the username, then compare the password hash returned from the DB with the input password using password_verify().

Also, when initially writing the hash to the DB on password creation (using password_hash()) there is no need to escape the hash. password_hash() is not used at all in the password verification process.

From a quick glance at the functions it seems that you may have got the test the wrong way round.

You should store the hashed version of the password in the db and then compare that with the password provided through the $_POST.. then the rest would go like..

$getuser = $connection->prepare('SELECT `password` 
                                        FROM `users` WHERE `username` = ?');
$getuser->bind_param('s', $username);
$getuser->execute();
$userdata = $getuser->get_result();
$row = $userdata->fetch_array(MYSQLI_ASSOC);
echo 'Password from form: ' . $hashedpassword . '<br />';
echo 'Password from DB: ' . $row['password'] . '<br />';
if (password_verify($password, $row['password'])) {
    // $password being $_POST['password-sign-in']
    // $row['password'] being the hashed password saved in the database
    echo 'Success.';
    exit();
} else {
    echo 'Fail.';
    exit();
}

Have you attempted to change the single quotes like ':

$getuser = $connection->prepare('SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?');
$getuser->bind_param('ss', $username, $hashedpassword);

To double quotes like "

$getuser = $connection->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?");
$getuser->bind_param("ss", $username, $hashedpassword);

Also, why are you matching against password? Perhaps this would work for your test case:

$getuser = $connection->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ?");
$getuser->bind_param("s", $username);

EDIT Also, you are essentially double-hashing the password when you do your check:

if (password_verify($row['password'], $hashedpassword)) {

Just do this instead:

if (password_verify($password, $row['password'])) {

The issue is that password_verify has the syntax of:

boolean password_verify ( string $password , string $hash )

You need to send the plain/non-hashed password in the first param & then place the hashed value in the second param. Try it out.

the problem is usually when you hash user input from a form it is hashed as if it has double quotes. that's why you see the hash starting with $2y$10...... I think you should try to solve it from this point. if you are giving an answer also consider this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!