簡體   English   中英

password_verify - 密碼與 hash 不匹配

[英]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 為什么。

圖 1 圖 2

//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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM