为何输入正确密码时bcrypt的compare方法仍返回false?
登录API密码匹配失败问题
我用Postman测试登录API时遇到问题:注册API正常工作,会在保存密码到数据库前做哈希处理,但用相同凭证登录时,系统提示密码不匹配。
用户Schema定义
const mongoose = require("mongoose"); const bcrypt = require("bcrypt"); const Schema = mongoose.Schema; const userSchema = new Schema({ username: { type: String, required: true, unique: true, trim: true, minlength: 5 }, email: { type:String, required: true, unique: true, trim: true }, password: { type: String, required: true, trim: true, lowercase: true, minlength: 6 } });
密码哈希中间件
userSchema.pre("save", async function (next) { try{ const user = this; if (!user.isModified("password")) { return next(); } const salt = await bcrypt.genSalt(10); const hash = await bcrypt.hash(user.password, salt); user.password = hash; next(); } catch (error) { throw new Error(error); } });
登录功能代码
try{ const {username, password} = req.body; const { error } = loginValidation.validate(req.body); if (error) { return res.status(400).json({ message: error.details[0].message, type: "error"}); } const existingUser = await User.findOne({ username }); if (!existingUser){ return res.status(401).json({message:"Invalid username", type:"error"}); } const passwordMatch = await bcrypt.compare(password, existingUser.password); if(!passwordMatch){ return res.status(401).json({message:"Invalid password", type:"error"}); } res.status(200).json({message: "Login successful", type:"success"}); }catch(error){ console.log(error.message + "Error from controllers/auth.js"); res.status(500).json({message:"Error authenticating user", type:"error"}); }
排查与解决步骤
- 统一密码大小写处理:Schema里密码字段设置了
lowercase: true,存储时密码会被转小写,但登录时传入的原始密码如果含大写,会导致比对失败。要么登录时把密码转小写,要么去掉Schema中的lowercase: true(如果业务不需要强制小写)。
示例修改登录代码:const passwordMatch = await bcrypt.compare(password.toLowerCase(), existingUser.password); - 验证哈希执行有效性:注册成功后,直接查看数据库中的哈希值,同时手动用
bcrypt.hash处理原始密码,对比两者是否一致。若不一致,检查pre("save")中间件是否正确绑定到User模型,避免模型创建后才定义中间件的情况。 - 确认用户查询准确性:在登录代码中打印
existingUser.password,确保拿到的是哈希值而非原始密码,同时确认findOne({ username })查询到的是目标用户(避免用户名大小写差异导致查错用户)。 - 检查bcrypt版本兼容:确保项目中bcrypt版本统一,不同版本的哈希算法差异可能导致比对失败,可尝试重新安装依赖。
内容的提问来源于stack exchange,提问作者totalNoob
相关产品推荐
相关产品推荐

