Password_verify 未验证数据库中的散列

Password_verify is not verifying the hash in the database

我正在尝试让用户登录,但每次我尝试验证密码时都会收到错误消息。用户名已通过验证。我的密码由 password_hash 存储在数据库中。例如,假设我注册了一个用户名 'thisIsAUser',密码是 'thisIsAUsersPassword'。散列类似于:y$VR5FKZVLP6/43adb1PsGD.bsmrzp15jdftotz6xubDQtypZ1rKEFW。错误将是 if(password_verify) 的 else 语句。请注意,不匹配的用户名的 else 语句有一个“.”。最后,密码不匹配时有一个 '!'。

登录脚本:

<?php 
session_start();
            
$link = mysqli_connect("localhost", "root", "Yuvraj123", "KingOfQuiz");
if(mysqli_connect_error()) {
    die("Couldn't connect to the database. try again later.");
} 
    
$query = "SELECT * FROM `users`";
    
if($result = mysqli_query($link, $query)) {
    $row = mysqli_fetch_array($result);
}
            
// define variables and set to empty values
$loginSignupButton = "";
$loginUsername = "";
$loginPassword = "";
       
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $loginUsername = form_input($_POST["loginUsername"]);
    $loginPassword = form_input($_POST["loginPassword"]);
    $loginSignupButton = form_input($_POST["loginSignupButton"]);
}
    
function form_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}
        
// define variables and set to empty values
$loginUsernameError = "";
$loginPasswordError = "";
$error = "";
$loggingInUsername = "";
$unhashedPasswordThingyMajig = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (empty($_POST["loginUsername"])) {
        $loginUsernameError = "<p style='color: red'>Username is required</p>";
        echo $loginUsernameError;
    } else {
        $loginUsername = form_input($_POST["loginUsername"]);
    }
    if (empty($_POST["loginPassword"])) {
        $loginPasswordError = "<p style='color: red'>Password is required</p>";
        echo $loginPasswordError;
    } else {
        $loginPassword = form_input($_POST["loginPassword"]);
    }
    
    if($_POST['loginActive'] == "0") {
                  
        $query = "SELECT * FROM users WHERE username = '". mysqli_real_escape_string($link, $_POST['loginUsername'])."' LIMIT 1"; 
        $result = mysqli_query($link, $query);
        if(mysqli_num_rows($result) > 0) {
            $error = "<p style='color: red'>That username is already taken.</p>";
            echo $error;
        } else {
            header ('location: signup.php');
        }
    } elseif($_POST['loginActive'] == "1") {
        $sql = "
                    SELECT *
                    FROM users
                    WHERE username = ?
                "; 
        $query  = mysqli_prepare($link, $sql);
        mysqli_stmt_bind_param($query, "s", $_POST["loginUsername"]);
        mysqli_stmt_execute($query);
        $result = mysqli_stmt_get_result($query);
                
        if (mysqli_num_rows($result)) {
            $logInPassword = $_POST['loginPassword'];
            if(password_verify($logInPassword, $row['password'])) {
                echo "Hello World!";
            } else {
                $error = "<p style='color: red'> The Password and Username combination Is not Valid!</p>";
                echo $error;
            }
        } else {
            $error = "<p style='color: red'> The Password and Username combination Is not Valid.</p>";
            echo $error;
        }   
    } 
}
?>

表格(这是登录表格,不是注册表格):

<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header" id="LoginModalTitle">
        <h5 class="modal-title" id="exampleModalLabel LoginModalTitle">Login</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true" style="color: white">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" id="modal-details">
      <div class="form-group">
        <input type="hidden" id="loginActive" name="loginActive" value="1">
        <label for="loginUsername">Username</label>
        <input type="text" class="form-control formInput" id="inputUsername" placeholder="Eg: RealKingOfQuiz" name="loginUsername" autocomplete="off" required>
        <p><span class="error"><?php echo $loginUsernameError;?></span><p>
      </div>
      <div class="form-group">
        <label for="loginPassword">Password</label>
        <input type="password" class="form-control formInput" id="inputPassword" name="loginPassword" required autocomplete="on">
        <small><a href="" id="forgotPassword" style="color: blue; text-decoration: none">Forgot Password?</a></small>
        <p><span class="error"><?php echo $loginPasswordError;?></span></p>
      </div>
        <p><span class="error"><?php echo $error;?></span></p>
        <div class="alert alert-danger" id="loginAlert"></div>
        </form>
      </div>
      <div class="modal-footer">
        <a id="toggleLogin">Sign Up?</a>
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
        <button class="btn btn-success" id="LoginSignUpButton" name="loginSignupButton" form="modal-details" disabled>Login</button>
        </div>
    </div>
  </div>
</div>

您从未获取登录用户的行。当您检查 $row['password'] 时,它正在检查 table 中的第一个密码,该密码来自开头的 SELECT * FROM users 查询剧本。

您需要在为用户查询行后调用mysqli_fetch_assoc()

        if (mysqli_num_rows($result)) {
            $logInPassword = $_POST['loginPassword'];
            $row = mysqli_fetch_assoc($result);
            if(password_verify($logInPassword, $row['password'])) {
                echo "Hello World!";
            } else {
                $error = "<p style='color: red'> The Password and Username combination Is not Valid!</p>";
                echo $error;
            }
        } else {
            $error = "<p style='color: red'> The Password and Username combination Is not Valid.</p>";
            echo $error;
        }   

如果您更新代码部分...

$result = mysqli_stmt_get_result($query);

...到代码块的末尾,下面是;那么它应该可以工作。

问题是您从错误的结果集中读取密码。

$result     = mysqli_stmt_get_result($query);
$dbPassword = mysqli_fetch_assoc($result)["password"] ?? null;

if ($dbPassword) {
    $logInPassword = $_POST['loginPassword'];
    if(password_verify($logInPassword, $dbPassword)) {
        echo "Hello World!";
    } else {
        $error = "<p style='color: red'> The Password and Username combination Is not Valid!</p>";
        echo $error;
    }
} else {
    $error = "<p style='color: red'> The Password and Username combination Is not Valid.</p>";
    echo $error;
}