【问题标题】:php password_verify() hash and pass won't matchphp password_verify() 哈希和传递不匹配
【发布时间】:2016-03-31 06:57:20
【问题描述】:

我将密码存储在使用password_hash() 散列的数据库中,并尝试使用password_verify() 验证登录时的密码。出于某种原因,password_verify() 一直返回 false。

我阅读了关于这个函数的文档,它说要确保函数中使用的散列在单引号 ' ' 之间,否则它会因为 $'s 而读取散列,就像它是三个变量一样,所以我尝试了像这样写 $valid '$valid'。但这没有用。

当我回显 $valid 时,输出为 $2y$10$zzZCN7UlukvY2skb3ELVp.4y3Oc7NJTEsFyqdstqYxT

当我回显 $check 时,输出为 123,这是用于创建帐户的密码。

这是我的login.php的一部分,这也是我觉得问题所在。

$emailLogin = mysqli_real_escape_string($con, $_POST['emailLogin']);

$passLogin = mysqli_real_escape_string($con, $_POST['passLogin']);

$query = "SELECT `pass` FROM `user` WHERE `email`='$emailLogin'";

$result = mysqli_query($con, $query);

$row = mysqli_fetch_array($result);

$pass = $row['pass']; 

$key = VUP($passLogin, $pass);

这是我的 verify.php 的一部分

function VUP($check, $valid){

if (password_verify($check, $valid)) {
$key = 1;

} else {
echo 'Invalid password.';
$key = 0;
die();
}
return $key;

}

也是 verify.php 的一部分

function SHP($password){

$hash = password_hash('$password', PASSWORD_BCRYPT);

return $hash;

}

任何建议都会很有帮助。

【问题讨论】:

  • 我可以建议一个完整的代码更改吗?你应该把查询放在函数VUP里面,你不需要从数据库中获取密码来检查它,你可以让mysql来完成这项工作。
  • 如果你使用字符串进行测试,你只需要使用简单的引号。 password_verify() 得到一个纯文本密码作为第一个参数,一个散列密码作为第二个参数。
  • 好的,我可以将查询移到 VUP 中,但是如何在不从数据库中获取通行证的情况下进行验证?
  • 请参阅以下链接 php.net/manual/en/mysqli.error.phpphp.net/manual/en/function.error-reporting.php 并将其应用于您的代码。还要确保列足够长。如果不是,MySQL 将静默失败。
  • $2y$10$zzZCN7UlukvY2skb3ELVp.4y3Oc7NJTEsFyqdstqYxT 你去吧,它只有 50 长并且无效/太短。它应该是 60(建议 255),所以没有正确存储。您将需要增加列的长度,清空这些行并重新开始。 RTM php.net/manual/en/function.password-hash.php - “因此,建议将结果存储在可以扩展超过 60 个字符的数据库列中(255 个字符是一个不错的选择)。” - 想要这个作为答案吗?我认为应该是。

标签: php mysql mysqli truncate


【解决方案1】:

“当我回显 $valid 时,输出为 $2y$10$zzZCN7UlukvY2skb3ELVp.4y3Oc7NJTEsFyqdstqYxT”

$2y$10$zzZCN7UlukvY2skb3ELVp.4y3Oc7NJTEsFyqdstqYxT 哈希只有 50 长并且无效/太短,正如我所说,MySQL 将默默地失败;错误报告/检查在这里没有帮助。

密码的列长应该是60(建议255),所以原来没有正确存储。

您需要清除密码列/或表,增加列的长度,然后重新开始。

参考:

“因此,建议将结果存储在可以扩展超过 60 个字符的数据库列中(255 个字符是一个不错的选择)。”


您还可以将查询修改为:

$con = new mysqli("xxx", "xxx", "xxx", "xxx");
if ($con->connect_error) {
    die('Connect Error (' . $con->connect_errno . ') '
            . $con->connect_error);
}

$query = "SELECT `pass` FROM `user` WHERE `email`='$emailLogin'";
$result = $con->query($query);

// error checking on the query
if (!$result) {
    echo "<p>There was an error in query: $query</p>";
    echo $con->error;
}

$row_hash = $result->fetch_array();
if (password_verify($passLogin, $row_hash['pass'])) {
    echo "Success!";
}

编辑:

从我留给 OP 的评论中添加:

您的验证功能需要与您的数据库建立连接,这就是我觉得这里发生的事情(可变范围)。因此,您需要使用global $con; 或将连接(变量)传递给您的函数(这在大多数情况下会更好)。

我不知道您是否正在为该函数执行“包含”,如果是,那么这就是另一个问题。

即:function VUP($con, $check, $valid){function VUP($check, $valid){ global $con; - 尝试两者。使用$result = mysqli_query($con, $query) or die(mysqli_error($con)); 而不是您现在拥有的。

【讨论】:

    猜你喜欢
    • 2014-04-17
    • 2014-12-30
    • 1970-01-01
    • 2019-10-10
    • 2014-05-19
    • 1970-01-01
    • 2021-04-23
    • 2017-11-22
    • 1970-01-01
    相关资源
    最近更新 更多