我正在制作一个注册和登录表单,要求提供用户的电子邮件和密码。在我的注册文件中,我对用户提供的密码进行了散列处理,并使用函数 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/