使用bcrypt验证密码失败:正确账号密码仍提示无效
问题排查与解决方案
1. 未处理用户不存在的场景
你的代码没有判断查询结果是否为空,如果输入的用户名不存在,results[0]会是undefined,访问results[0].user_password会触发错误,最终也会走到错误提示分支。先补上这个判断:
app.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; const searchSql2 = 'SELECT * FROM users WHERE user_name = ?' con.query(searchSql2, [username], async (err, results, fields) => { if (err) throw err; // 先判断用户是否存在 if (results.length === 0) { return res.send("Invalid username or password"); } const hashedPassword = results[0].user_password; const isValid = bcrypt.compareSync(password, hashedPassword); if (isValid) { req.session.loggedin = true; req.session.username = username; return res.redirect('./home'); // redirect已结束响应,无需res.end() } else { res.send("Invalid username or password"); } }) })
2. 检查数据库字段长度
bcrypt生成的哈希值固定为60个字符,如果你的users表中user_password字段长度小于60(比如设成VARCHAR(50)),哈希值会被截断,导致对比失败。修改字段类型为VARCHAR(60)或更长(比如VARCHAR(255))。
3. 验证密码哈希生成逻辑
确保用户注册时,你是用bcrypt正确生成哈希并存入数据库的,注册代码示例:
const saltRounds = 10; const hashedPassword = bcrypt.hashSync(userInputPassword, saltRounds); // 将hashedPassword插入到user_password字段
如果注册时直接存明文密码、或用了其他哈希算法,bcrypt对比必然失败。
4. 处理输入密码的前后空格
用户输入密码时可能不小心带了前后空格,可在对比前去除:
const password = req.body.password.trim();
内容的提问来源于stack exchange,提问作者JUSTOO
相关产品推荐
相关产品推荐

