php - 尝试使用登录表单中的密码验证数据库中的散列密码

标签 php mysql database password-encryption

我正在制作一个注册和登录表单,要求提供用户的电子邮件和密码。在我的注册文件中,我对用户提供的密码进行了散列处理,并使用函数 password_hash 将其存储在数据库中。在我的登录表单中,我尝试使用数据库中存储的散列密码验证用户提供的密码,但失败了。我使用了 password_verify 函数。这是注册代码的片段:

注册文件片段

if(!isset($error)){
    
    //hash the password
    $hashedpassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
    echo $hashedpassword;
    
    try {
        $sql = "INSERT INTO users (mail, password, province) VALUES (:mail, :password, :province)";
        $stmt = $db->prepare($sql);

        //Bind variables
        $stmt->bindValue(':mail', $mail);
        $stmt->bindValue(':password', $hashedpassword); 
        $stmt->bindValue(':province', $province);

        //Execute the statement and insert the new account.
        $result = $stmt->execute();

        //If the signup process is successful.
        if($result){
            echo $hashedpassword;
            exit;
        }
    
     } 
     catch(PDOException $e) {
     $error[] = $e->getMessage();
     }
}

数据库中的哈希密码

对于这些密码,我得到以下存储在数据库中的散列密码:

足球: $2y$10$q0Y8Mfdl75Dt8op7WaqQM.t5y4LMO6gfYwmbycL1xRMiUUQu8dtWm$2y$10$q0Y8Mfdl75Dt8op7WaqQM.t5y4LMO6gfYwmbycL1xRMiUUQu8dtWm

蟋蟀:
$2y$10$Pyoz1XC0skRjHLjxHdrYYeYplY98w4uOp23QpZb/VNN0y41/6YPJC$2y$10$Pyoz1XC0skRjHLjxHdrYYeYplY98w4uOp23QpZb/VNN0y41/6YPJC

密码行的类型是 varchar(255) 排序规则是 utf8mb4_general_ci 密码是这样存储的:
$2y$10$q0Y8Mfdl75Dt8op7WaqQM.t5y4LMO6gfYwmbycL1xRM... $2y$10$Pyoz1XC0skRjHLjxHdrYYeYplY98w4uOp23QpZb/VNN...

当我将鼠标悬停在密码上时,它会显示“原始长度 60”。

登录文件片段

这是我的登录文件代码片段:

$mail = htmlspecialchars_decode($_POST['mail'], ENT_QUOTES);

if(!filter_var($mail, FILTER_VALIDATE_EMAIL) and !empty($_POST['mail'])) {
    $error[] = 'Please enter a valid email address';
}
$stmt = $db->prepare('SELECT mail, password FROM users WHERE mail = :mail');
$stmt->execute(array(':mail' => $mail));
$row = $stmt->fetch(PDO::FETCH_ASSOC);

if(!empty($row['mail'])){
$error[] = 'Email provided is good.';
}

$password = $_POST['password'];
$stmt = $db->prepare('SELECT password FROM users WHERE password = :password');
$stmt->execute(array(':password' => $password));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$checkpass = $row['password'];
echo $checkpass;
if(password_verify($password, $row['password'])) {
    $error[] = 'Password provided is good.'; 
}

检查是否可以在数据库中找到电子邮件工作正常,因为它给了我错误消息(我需要将其更改为正常消息)。 但是我无法使密码验证正常工作。我试图通过 $checkpass = $row['password'];
查看代码提取数据库的内容 echo $checkpass; 但它不返回任何东西(可能是因为它只返回 0 或 1 值?)。 也许它与我尝试从数据库中选择散列密码的方式有关?或者我将它们插入数据库的方式,或者 MySQL 表选项?这可能是一个简单的修复,但我尝试了很多不同的方法,但我无法让它工作。希望你们能提供帮助!

最佳答案

第二个查询似乎没有用,因为在第一个查询中您已经选择了邮件和密码字段。所以你应该只需要执行第一个查询,检查用户是否有效,然后使用 password_verify 方法检查密码。

您的第二个查询失败(可能)是因为在您传递明文的情况下,但在数据库中存在散列密码,因此您将永远找不到任何东西。在执行前检查打印第二个查询。

关于php - 尝试使用登录表单中的密码验证数据库中的散列密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48421340/

相关文章:

mysql - mysql查询的解释

sql - 在 Oracle Sql 查询中获取格式化字符串

函数参数前的 PHP 类型,好还是坏?

javascript - 通过 post 传递 json 对象以及其他数据

php - 无法显示来自mysql php的两个图像链接

php - Mysql 内连接在 Mysql 5.1 上不起作用

MYSQL 选择其中 SUM()

数据库设计对两个表之间双向外键的考虑

php - 学术测验应用程序的数据库设计

PHP : implementing states with objects