无法使用password_verify($ password,$ hash)

Tri*_*man 3 php password-hash

所以我有一个注册页面和一个登录页面,注册页面工作得很好,但登录页面似乎没有工作,我似乎无法弄明白.

我的数据库似乎正在工作,因为我能够将哈希密码回显到登录页面,它似乎与password_verify()有关

注册页面(工作)

<?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();

}
Run Code Online (Sandbox Code Playgroud)

登录页面(不工作)

<?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;

    }
}
Run Code Online (Sandbox Code Playgroud)

Fun*_*ner 8

这里的问题是\n:

$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
                                                         ^^
Run Code Online (Sandbox Code Playgroud)

是(无形地)在密码/散列末尾添加回车/换行符.

你可以删除它.

$h_p = password_hash($pass, PASSWORD_DEFAULT, $options);
Run Code Online (Sandbox Code Playgroud)

trim()它:

$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
$h_p = trim($h_p);
Run Code Online (Sandbox Code Playgroud)

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

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

手册中的示例如下:

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
Run Code Online (Sandbox Code Playgroud)

但做:

$var = password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
Run Code Online (Sandbox Code Playgroud)

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

  • 所以现在你需要清除你现在的哈希值并重新开始使用一组新的哈希值.

看看这个沙箱代码示例

运行时,它会输出如下内容:

$2y$10$494GPYzaynEkfYxE3wcAj.OtwBU3CCwTMXOHKbdJmOqwMXRmq6v1u
61

如果URL稍后是404,这里是上面的代码:

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

补充说明; 你也应该SELECT像你一样使用准备好的陈述INSERT; 它更安全.