Node.js中bcrypt哈希密码登录提示无效密码问题排查求助
bcrypt密码匹配失败的排查与解决
下面是针对你遇到的问题,整理的几个最可能的原因和解决办法:
1. 数据库password字段长度不足
bcrypt生成的哈希密码固定是60个字符,如果你的数据库user表中password字段的长度设置小于60(比如VARCHAR(50)),存储时哈希值会被自动截断,导致登录时对比的是不完整的哈希串,自然匹配失败。
解决:
修改数据库表结构,将password字段改为VARCHAR(255)或TEXT类型,确保能完整存储哈希值。之后重新创建测试账号,再尝试登录。
2. 密码存在多余前后空格
用户输入密码时可能误加了前后空格,而你在注册和登录环节都没做去空格处理,导致哈希的密码和输入的带空格密码不匹配。
解决:
在注册和登录接口中对密码做trim处理:
- 注册接口:
const password = req.body.password.trim(); - 登录接口:
const password = req.body.password.trim();
3. 确认数据库取出的哈希值完整
在登录接口中添加日志,打印取出的存储密码,确认它和数据库中存储的完全一致:
console.log('存储的哈希密码:', storedPassword); console.log('用户输入的密码:', password);
如果打印出的storedPassword和数据库中的值不一样,说明存储或读取时出现了字段截断、编码等问题。
4. 改用async/await简化异步逻辑(可选)
虽然你的回调写法没问题,但异步回调容易隐藏小错误,改用async/await能让逻辑更清晰,也方便排查:
修改后的注册接口:
const util = require('util'); // 先把db.query转为支持promise的方法 db.query = util.promisify(db.query); app.post('/add_user', async (req, res) => { console.log("Post request on /add_user"); try { const { name, lastname, email, password, address, number } = req.body; const trimmedPassword = password.trim(); const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(trimmedPassword, salt); const sql = "INSERT INTO user (name, lastname, email, password, address, number) VALUES (?, ?, ?, ?, ?, ?)"; const values = [name, lastname, email, hashedPassword, address, number]; await db.query(sql, values); console.log("User added successfully"); res.status(200).send('User added successfully'); } catch (err) { console.error('Error:', err); res.status(500).send('Server error'); } });
修改后的登录接口:
app.post('/login0', async (req, res) => { try { const { email, password } = req.body; const trimmedPassword = password.trim(); const sql = "SELECT * FROM user WHERE email = ?"; const values = [email]; const [result] = await db.query(sql, values); if (result.length === 0) { console.log("Account not found"); return res.status(401).json({ message: "Account not found" }); } const storedPassword = result[0].password; const isMatch = await bcrypt.compare(trimmedPassword, storedPassword); if (isMatch) { console.log("Password match, login successful"); return res.status(200).json({ message: "Login successful", user: result[0] }); } else { console.log("Invalid password"); return res.status(401).json({ message: "Invalid password" }); } } catch (err) { console.error("Database error: ", err); return res.status(500).json({ message: "Login failed: Database error" }); } });
内容的提问来源于stack exchange,提问作者anas
相关产品推荐
相关产品推荐

