[英]password_verify - password doesn't matches the hash
我有一個登錄系統。 您可以注冊一個用戶並稍后登錄(在這種情況下,password_verify 完成了它的工作)。 然后我有一個密碼恢復系統。 您會收到一封電子郵件,其中包含帶有令牌等的鏈接。 您更改密碼並在數據庫中更改(我可以通過更改的哈希看到它)。 然后,如果您嘗試使用新密碼登錄,它會顯示密碼錯誤,舊密碼也不會。
/// new password is set
$newPwdHash = password_hash($pwd, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, 'ss', $newPwdHash, $tokenEmail);
mysqli_stmt_execute($stmt);
$pwdCheck = password_verify($pwd, $row['pwdUsers']);
我不知道它是否有幫助,但是如果您在恢復密碼時嘗試設置的不是散列密碼,而是通常的密碼,它會在數據庫中將其更改為空的空白 idk 為什么。
//login
if (isset($_POST['login'])) {
require 'db.inc.php';
$mailuid = $_POST['mailuid'];
$pwd = $_POST['pwd'];
if (empty($mailuid) || empty($pwd)) {
header('Location: ../index.php?error=empty');
exit();
} else {
$sql = 'SELECT * FROM users WHERE uidUsers=? OR emailUsers=?';
$stmt = mysqli_stmt_init($link);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header('Location: ../index.php?error=sql');
exit();
} else {
mysqli_stmt_bind_param($stmt, 'ss', $mailuid, $mailuid);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
if ($row = mysqli_fetch_assoc($result)) {
$pwdCheck = password_verify($pwd, $row['pwdUsers']);
if (!$pwdCheck) {
header('Location: ../index.php?error=wrongpwdormail');
exit();
} elseif ($pwdCheck) {
session_start();
$_SESSION['id'] = $row['idUsers'];
$_SESSION['uid'] = $row['uidUsers'];
header('Location: ../index.php?login=success');
exit();
} else {
header('Location: ../index.php?error=wrongpwdormail');
exit();
}
} else {
header('Location: ../index.php?error=nouser');
exit();
}
}
}
} else {
header('Location: ../index.php');
exit();
}
//reset
$tokenEmail = $row['pwdResetEmail'];
$sql = 'SELECT * FROM users WHERE emailUsers=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error2';
exit();
} else {
mysqli_stmt_bind_param($stmt, 's', $tokenEmail);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
if (!$row = mysqli_fetch_assoc($result)) {
echo 'error3';
exit();
} else {
$sql = 'UPDATE users SET pwdUsers=? WHERE emailUsers=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error4';
exit();
} else {
$newPwdHash = password_hash($pwd, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, 'ss', $newPwdHash, $tokenEmail);
mysqli_stmt_execute($stmt);
$sql = 'DELETE FROM pwdReset WHERE pwdResetEmail=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error5';
exit();
} else {
mysqli_stmt_bind_param($stmt, 's', $tokenEmail);
mysqli_stmt_execute($stmt);
header('Location: ../signup.php?newpwd=updated');
}
}
}
}
注意:除非您在登錄(isset)部分之外的多個部分上復制變量,否則它很可能是未定義的,因此散列未定義的變量。 所以密碼永遠不會匹配。
請注意您是如何在重置部分使用變量$pwd
的,即使您在“登錄”部分中創建了$pwd
變量。 如果代碼的兩個部分都包含在一個文件中並且順序與您在 StackOverflow 上發布的順序一致,我非常懷疑您是否達到了該部分。
if (isset($_POST['login'])) {
$mailuid = $_POST['mailuid'];
$pwd = $_POST['pwd'];
//NOTICE: unless you are duplicating the variables on multiple parts
//including OUTSIDE of the login (isset) part, it most likely is undefined
//thus, hashing an undefined variable. So the password will NEVER match.
} else {
//header('Location: ../index.php');
//exit(); //will halt execute, so it's interesting that you're even reaching the reset part.
//Unless the reset part and login part aren't in the same file.
}
重置部分和登錄部分是否在同一個文件中?
else {
$newPwdHash = password_hash($pwd, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, 'ss', $newPwdHash, $tokenEmail);
mysqli_stmt_execute($stmt);
$sql = 'DELETE FROM pwdReset WHERE pwdResetEmail=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error5';
exit();
} else {
mysqli_stmt_bind_param($stmt, 's', $tokenEmail);
mysqli_stmt_execute($stmt);
header('Location: ../signup.php?newpwd=updated');
}
}
我建議您為重置部分創建一個專用頁面,您可以在其中執行以下操作:
if (isset($_POST["recovery"])) { // or whatever kind of check you wish to do prior to firing your code.
$tokenEmail = $row['pwdResetEmail']; //no idea where you created this ->
//$row["pwdResetEmail"]; I assume it's a part you're either not showing us,
//or this isn't working either. I am guessing the first one (that you aren't
//showing us where you retrieve it), or else it would not be possible to
//change anything and the query should fail (correct me if I am wrong here guys).
$pwd = // NOTICE: assign the password. May it be a POST or a GET or whatever
$sql = 'SELECT * FROM users WHERE emailUsers=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error2';
exit();
} else {
mysqli_stmt_bind_param($stmt, 's', $tokenEmail);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
if (!$row = mysqli_fetch_assoc($result)) {
echo 'error3';
exit();
} else {
$sql = 'UPDATE users SET pwdUsers=? WHERE emailUsers=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error4';
exit();
} else {
$newPwdHash = password_hash($pwd, PASSWORD_DEFAULT); //NOTICE:
//NOW THE VARIABLE $PWD IS DEFINED
mysqli_stmt_bind_param($stmt, 'ss', $newPwdHash, $tokenEmail);
mysqli_stmt_execute($stmt);
$sql = 'DELETE FROM pwdReset WHERE pwdResetEmail=?';
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo 'error5';
exit();
} else {
mysqli_stmt_bind_param($stmt, 's', $tokenEmail);
mysqli_stmt_execute($stmt);
header('Location: ../signup.php?newpwd=updated');
}
}
}
}
}
KK,我進行了調試,這就是我發現的:當我需要 db.php 文件時,有一個名為 $pwd 的變量是空的,這就是為什么當我嘗試設置新密碼時沒有值的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.