You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何输入正确密码时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:07:04