【问题标题】:Unable to use password_verify($password, $hash)无法使用 password_verify($password, $hash)
【发布时间】:2017-02-19 04:15:18
【问题描述】:

所以我有一个注册页面和一个登录页面,注册页面工作得很好,但登录页面似乎不起作用,我似乎无法弄清楚。

我的数据库似乎正在工作,因为我能够将散列密码回显到登录页面上,这似乎与 密码验证()

注册页面(工作中)

<?php 
include("assets/includes/conn.php");

$user = $_POST['username'];
$pass = $_POST['pass'];
$cPass = $_POST['c-pass'];
$email = $_POST['email'];

$options = [
    'cost' => 11
];

if($pass == $cPass){

    $stmt = $conn->prepare("INSERT INTO users (username, pass, email) VALUES (?, ?, ?)");
    $stmt->bind_param("sss", $user, $h_p, $email);

    $user = $_POST['username'];
    $h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
    $email = $_POST['email'];
    $stmt->execute();

    echo "Created";
    echo $h_p;
    $stmt->close();
    $conn->close();

}

登录页面(不工作)

<?php 
include("assets/includes/conn.php");

$username = $_POST['username'];
$password = $_POST['pass'];

$sql = "SELECT * FROM users WHERE username = '$username'";
$result = $conn->query($sql);

if ($result->num_rows == 1){
    $row = $result->fetch_assoc();
    $hash = $row['pass'];

    if(password_verify($password, $hash)){
        echo "Yes";
    } else {
        echo "No<br/>";
        echo "" . $hash . "<br/>";
        echo $password;

    }
}

【问题讨论】:

  • 我对它失败的原因有一些想法,但您可以在下面看到答案。
  • 确保您是displaying errors,以防您遇到变量未正确发送到脚本等问题。
  • @Mike 问题是我不认为这是一个错误,它只是告诉我密码不正确,即使它是正确的,这可能与它被散列有关
  • @TristanSchlarman 不要假设任何事情。也许您没有正确地将值传递给脚本。
  • 欢迎来到 Stack @TristanSchlarman 干杯

标签: php password-hash


【解决方案1】:

这里的问题是\n in:

$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
                                                         ^^

是(不可见)在您的密码/哈希末尾添加carriage return/linefeed

您可以删除它。

$h_p = password_hash($pass, PASSWORD_DEFAULT, $options);

trim()它:

$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
$h_p = trim($h_p);

老实说,我不知道为什么 password_hash() 上的手册没有提及它以及将其存储在数据库(或文件)中的用途。

注意:这里的文档没有使用,是为示例分配一个变量 ,这就是这里的问题所做的。有些人可能认为使用该示例并为其分配一个变量会起作用; 不会;不是为了存储散列然后验证它。

手册中的示例如下:

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";

但是做:

$var = password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";

实际上(理论上)将包含一个 61 长度的字符串(因为连接的换行符),而不是没有换行符的预期 60。

  • 因此,现在您需要清除当前的哈希值并从一组新的哈希值重新开始。

看看this sandbox code example

运行时会输出如下内容:

$2y$10$494GPYzaynEkfYxE3wcAj.OtwBU3CCwTMXOHKbdJmOqwMXRmq6v1u 61

以防万一 URL 稍后是 404,这是上面的代码:

<?php
$foo = password_hash('mypass',  PASSWORD_DEFAULT)."\n";
echo $foo;
echo strlen($foo);

添加注释;您还应该为您的SELECT 使用准备好的语句,就像您为INSERT 所做的那样;它更安全。

【讨论】:

  • @TristanSchlarman 不客气。我昨晚有问题,但不得不上床睡觉。然后我今天重新审视了这个问题以添加我的答案。现在可以将其标记为已解决。
  • @TristanSchlarman 只需单击向上/向下箭头下的灰色勾号,直到它变为绿色;这就是问题被标记为已解决/已关闭的方式。
  • 有趣的一点,我以前做过,但从来没有弄清楚为什么会搞砸
  • @Darren 我认为您使用的代码现在已更改;还是因为不包含\n而最终使用了其他东西?
猜你喜欢
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 2023-03-11
相关资源
最近更新 更多