PHP中password_verify与mysqli预处理语句配合失效求助
排查password_verify验证失败的问题
我来帮你揪出这个密码验证失效的问题,先看几个关键的排查点:
1. 参数顺序搞反了!这是最常见的坑
password_verify()的正确参数顺序是:第一个参数是用户输入的明文密码,第二个参数是数据库里存储的哈希值。但你的代码里写反了:
password_verify($row['password'], $_POST['password'])
应该改成:
password_verify($_POST['password'], $row['password'])
这大概率就是导致验证失败的核心原因!
2. 检查数据库密码字段的长度
bcrypt生成的哈希值固定是60个字符,如果你数据库里的password字段长度不够(比如设成了VARCHAR(50)),哈希值会被截断,自然无法验证。建议把字段类型改成VARCHAR(255),留足够的冗余空间。
3. 确认数据库中的哈希格式正确
输出一下$row['password'],看看是不是标准的bcrypt格式:它应该以$2y$开头,总长度是60个字符。如果不是,说明你存储的不是用password_hash()生成的bcrypt哈希(比如存了明文或其他算法的哈希),这也会导致验证失败。
4. 检查用户输入的密码是否被篡改
有没有在其他地方对$_POST['password']做了额外处理?比如自动trim、转义或者编码转换?可以临时加一行var_dump($_POST['password']);,看看实际拿到的密码和用户输入的是否一致(注意别在生产环境这么做,避免泄露明文密码)。
修正后的核心代码示例:
<?php include('../include/sessions.php'); if(isset($_POST['username'])) { $select = "SELECT username, firstname, lastname, email, userlevel, `password` FROM users WHERE username = ?;"; $stmt = $dbc->prepare($select); $stmt->bind_param("s", $_POST['username']); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc(); // 修正password_verify的参数顺序 if($row && password_verify($_POST['password'], $row['password'])) { $_SESSION['user'] = $row; header("Location: ../cust/home.php"); die; } else { echo "The username/password combination does not match our records. Please try again."; } } ?>
内容的提问来源于stack exchange,提问作者John Beasley
相关产品推荐
相关产品推荐

