PHP哈希密码无法通过password_verify验证,登录失败求助
解决登录时
password_verify验证失败的问题 我帮你排查了代码里的几个关键问题,这些就是导致登录失败的核心原因:
1. 登录表单的提交判断完全错误
你的登录脚本开头用了if (isset($_POST['Register']))来判断是否触发登录逻辑,但Register是注册表单的提交按钮name啊!登录表单的提交按钮应该是类似Login的命名(比如<button type="submit" name="Login">登录</button>),这就导致用户点击登录时,直接进入了else分支,跳转到../index.php?login=failure3,根本没执行到密码验证的环节。
2. Session赋值的语法错误
就算前面的判断没问题,你在登录成功时的Session赋值也错了:
$_SESSION['username'] = $row[$Username];
这里的$Username是用户输入的用户名(比如用户输入"test"),但你应该取数据库表中的username字段值,正确写法是:
$_SESSION['username'] = $row['username'];
3. 注册代码里的潜在bug(虽不影响登录,但建议修复)
你的注册代码里有个语法错误,第一个preg_match少了要验证的变量:
// 错误写法 if (!preg_match("/^[a-zA-Z]*$/") || !preg_match("/^[a-zA-Z]*$/", $Last)) // 正确写法 if (!preg_match("/^[a-zA-Z]*$/", $First) || !preg_match("/^[a-zA-Z]*$/", $Last))
不过你说注册功能正常,可能是粘贴时的笔误,但还是建议修正,避免后续出现问题。
修正后的完整登录脚本
<?php session_start(); // 改成你登录表单提交按钮的name,比如Login if (isset($_POST['Login'])) { include 'dbh.inc.php'; $Username = mysqli_real_escape_string($conn, $_POST['Username']); $Password = mysqli_real_escape_string($conn, $_POST['Password']); // 空字段验证 if (empty($Username) || empty($Password)) { header("Location: ../index.php?login=empty"); exit(); } else{ $sql = "SELECT * FROM users WHERE username='$Username' OR email='$Username'"; $result = mysqli_query($conn, $sql); $resultcheck = mysqli_num_rows($result); // 检查用户是否存在 if ($resultcheck < 1) { header("Location: ../index.php?login=failure1"); exit(); } else { if ($row = mysqli_fetch_assoc($result)) { // 验证哈希密码 $hashedpwdCheck = password_verify($Password, $row["password"]); if ($hashedpwdCheck == false) { header("Location: ../index.php?login=failure2"); exit(); } elseif ($hashedpwdCheck == true) { // 正确赋值Session $_SESSION['username'] = $row['username']; header("Location: ../index.php?login=success"); exit(); } } } } } else { header("Location: ../index.php?login=failure3"); exit(); } ?>
额外调试与安全建议
- 确认登录表单的提交按钮
name属性和脚本里的判断完全一致,比如:<input type="submit" name="Login" value="登录"> - 调试时可以在密码验证前临时加
var_dump($row["password"], $Password); exit;,查看数据库中的哈希值和用户输入的密码是否正确(调试完务必删除) - 建议使用MySQLi预处理语句替代
mysqli_real_escape_string,能更彻底地防止SQL注入风险。
内容的提问来源于stack exchange,提问作者Shashank.boss




