【问题标题】:password_verify Always Returns False, even with proper variables usedpassword_verify 始终返回 False,即使使用了正确的变量
【发布时间】:2018-11-26 07:09:13
【问题描述】:

我的网页与许多网页一样以登录页面开头,如果用户没有帐户,他们可以注册。我的注册成功了,他们输入的用户密码成功地用password_hash 散列并发送到数据库。但是,当尝试登录时,password_verify 总是返回 false。考虑到我最初创建散列密码时犯了一个愚蠢的错误,我回显了我在password_verify 中用作第二个参数的变量。但是,它与数据库中的哈希完全匹配。可能是什么问题??下面提供了用于在注册期间创建密码和在登录时检查密码的缩短代码。

创建哈希密码

<?php
    session_start();
    require('db_credentials.php');

    $inputUsername = $_POST['createUsername'] ? $_POST['createUsername'] : null;
    $inputPassword = $_POST['createPassword'] ? $_POST['createPassword'] : null;
    $vPassword = $_POST['verifyPassword'] ? $_POST['verifyPassword'] : null;

     //protect database from corrupt user input
    $inputUsername = $mysqli->real_escape_string($inputUsername);
    $inputPassword = $mysqli->real_escape_string($inputPassword);
    $vPassword = $mysqli->real_escape_string($vPassword);

    //create connection
    $mysqli = new mysqli($servername, $username, $password, $dbname);

    $protectedPassword = password_hash($inputPassword, PASSWORD_DEFAULT);

    //Check if the passwords match
if($inputPassword != $vPassword){
    echo '<p style = "text-align: center;">Oops!The passwords you input did not match. Please try again.</p>';
    session_write_close();
    exit;
}

//Check for duplicate username
$query = "SELECT * FROM user_info WHERE username = ' ".$inputUsername." ' ";
$result = mysqli_query($mysqli, $query);

if(mysqli_num_rows($result) == 1) {
    echo '<p style = "text-align: center;">Oops! That Username is already taken. <br>Please try a different one.</p>';    
    session_write_close();
    exit;
}
//Username is not takin and the passwords match
else {
    $sql = "INSERT INTO user_info (username, password) VALUES (' ".$inputUsername." ', ' ".$protectedPassword." ')";
    echo '<p style = "text-align: center;">Success! You Have Made an Account!</p>';
    if($mysqli->query($sql) === TRUE) {
        session_write_close();
        exit;
    }
     else {
         echo "Error: " . $sql . "<br>" . $conn->error;
    }
}
?>

登录

<?php

    require('db_credentials.php');

    $inputUsername = $_POST['username'] ? $_POST['username'] : null;
    $inputPassword = $_POST['password'] ? $_POST['password'] : null;
    //protect database from corrupt user input
    $inputUsername = $mysqli->real_escape_string($inputUsername);
    $inputPassword = $mysqli->real_escape_string($inputPassword);

    $mysqli = new mysqli($servername, $username, $password, $dbname);        

    $query = "SELECT * FROM user_info WHERE username = ' ".$inputUsername." ' ";
    $result = $mysqli->query($query);

    //check if username is in database. If it is, do the passwords match?
    if($result->num_rows === 1) {

        $row = $result->fetch_array(MYSQLI_ASSOC);
        echo $row['password'] . "<br>"; //matches hash in database exactly
        echo $inputPassword; //matches the password I type in. Which is same I used to sign up.
        if(password_verify($inputPassword, $row['password'])){
            header("Location: puzzlerMember.php"); //this never happens
            exit; 
        }

    }    
    echo '<p style = "text-align: center;">Oops! Your Username/Password is incorrect. Sign up if you do not have an account.</p>'; //this always happens
    exit;

?>

注意:在数据库中,我将密码列设置为 VARCHAR(255)。 我看过许多类似的问题,但他们似乎都误认为数据库中的密码长度太短。如果他们没有,我尝试了解决方案的最佳答案。我完全不知道出了什么问题。 如果您能提供帮助,我提前感谢您。

【问题讨论】:

    标签: php login password-hash


    【解决方案1】:

    您正在转义密码,因此这会更改密码。不要将转义作为一种安全措施(这本身就是一种误解),而是使用准备好的语句。

    根据下面的评论,似乎需要澄清:您正在转义密码然后对其进行哈希处理,因此存储在数据库中的内容不是用户传递的内容,因此它永远不会找到用户传递的内容,因此,总是返回 false。

    相关: Should I mysql_real_escape_string the password entered in the registration form?

    更新 #1

    正如@mario 所发现的,当您将值传递给它时,您的查询中似乎有空格,它正在搜索您的表以查找不正确的值。

    阅读材料

    Prepared Statements

    【讨论】:

    • 我认为您需要强调的一点是密码在被散列之前被转义。 MySQL 不获取密码,它获取该密码的哈希,因此您在哈希之前转义的任何字符都将成为密码本身。
    • @Mike 我已经澄清了那部分。感谢您的反馈。
    • 请重新阅读您的注册码,您将$inputPassword 的值分配给$protectedPassword,该值被转义,然后您对其进行哈希处理,是的,问题出在注册上。
    • 我们确定这是相关的吗?当然,预先转义密码是错误的。但至少它在被误用于哈希验证方面是一致的。即便如此,输入密码包含引号的可能性有多大? // 看起来更像是用户名和哈希周围的额外空格可能有问题。
    • 我摆脱了转义,至于当我检查@Script47的链接时,它是无意义的,不应该用于密码。但是,删除它后,我仍然得到 password_verify 返回 false。
    猜你喜欢
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    相关资源
    最近更新 更多