如何正确使用PHP的Bcrypt类?登录验证失败问题求助
问题分析与修复方案
你的问题核心在于登录流程的逻辑完全搞反了,而且还存在严重的SQL注入风险,我来一步步帮你理清:
为什么每次验证都失败?
Bcrypt的核心特性就是每次哈希同一个密码都会生成不同的结果(因为自动生成随机盐并嵌入到哈希字符串中)。你现在的做法是:
- 把用户输入的密码重新哈希一次,然后用这个新生成的哈希去数据库里查找匹配的记录
- 但数据库里存的是用户注册时生成的哈希,和你这次登录生成的哈希肯定不一样,所以永远查不到数据
正确的登录流程应该是这样的:
- 先根据用户输入的
login从数据库取出对应的mdp_user(也就是注册时存储的Bcrypt哈希值) - 用Bcrypt的
checkPassword方法,把用户输入的原始密码和数据库取出的哈希值做比对 - 比对成功才说明密码正确,而不是用新哈希去查数据库
修复后的代码(同时修复SQL注入问题)
// 1. 先获取用户输入的登录信息(做基本的空值判断) $login = $_POST['login'] ?? ''; $inputPassword = $_POST['mdp_user'] ?? ''; // 2. 使用预处理语句查询数据库,彻底避免SQL注入 $sql = 'SELECT mdp_user FROM tgn_users WHERE login = ?'; $stmt = mysqli_prepare($connexion, $sql); mysqli_stmt_bind_param($stmt, 's', $login); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); // 3. 检查是否找到对应用户 if ($user = mysqli_fetch_assoc($result)) { // 4. 用数据库中存储的哈希值验证输入的密码 $pwdVerify = Bcrypt::checkPassword($inputPassword, $user['mdp_user']); if ($pwdVerify) { // 登录成功后的逻辑,比如设置会话 echo "登录成功!"; } else { // 密码不匹配 echo "密码错误,请重试!"; } } else { // 未找到该用户 echo "该账号不存在!"; } // 清理资源 mysqli_stmt_close($stmt); mysqli_close($connexion);
额外重要提醒
- 永远不要在登录时重新哈希密码:哈希操作只应该在用户注册/修改密码时执行一次,把结果存入数据库即可
- 坚决杜绝直接拼接用户输入到SQL语句中:预处理语句是防范SQL注入的标准做法,一定要养成习惯
- 处理用户输入前要做基础校验:比如检查
login和mdp_user是否为空,避免无效值进入业务逻辑
内容的提问来源于stack exchange,提问作者Rabah
相关产品推荐
相关产品推荐

