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

使用bcrypt登录失败,compare始终返回false求助排查

解决登录时bcrypt验证失败返回"Invalid login credentials"的问题

从你提供的注册和登录代码来看,注册功能正常但登录时密码比对失败,核心问题肯定出在bcrypt的密码哈希存储或比对环节,下面是几个最常见的排查方向和解决方法:

  • 检查User模型中password字段的长度限制
    bcrypt生成的哈希值固定是60个字符长度,如果你的User Schema里password字段的长度设置小于60(比如设成了varchar(50)或者mongoose里的maxlength:50),存储时哈希值会被截断,自然比对失败。你需要确保字段长度足够,比如mongoose Schema可以这么定义:

    const userSchema = new mongoose.Schema({
      firstName: String,
      lastName: String,
      email: String,
      password: { 
        type: String, 
        required: true, 
        minlength: 60, 
        maxlength: 60 
      }
    });
    

    要是用的是SQL数据库,也要对应把password字段的长度设为至少60。

  • 验证注册时的哈希值是否完整存储
    你可以在注册成功后直接查看数据库里的用户记录,确认password字段是完整的60位哈希字符串(格式一般是$2a$10$开头)。也可以在注册控制器里加个日志,输出生成的哈希值,确认没出问题:

    signup: function (req, res) {
      console.log(req.body)
      const hashedPassword = bcrypt.hashSync(req.body.password, 10);
      console.log('生成的密码哈希:', hashedPassword); // 检查是否是60位的有效哈希
      var user = new User({
        firstName: req.body.firstName,
        lastName: req.body.lastName,
        password: hashedPassword,
        email: req.body.email
      });
      user.save(function(err, result) {
        if (err) {
          return res.status(500).json({ title: 'An error occurred', error: err });
        }
        res.status(201).json({ message: 'User created', obj: result });
      });
    }
    
  • 确认登录时传入的密码没有异常
    有时候前端传入的密码可能带了前后空格,或者转义字符导致和用户实际输入不一致。你可以在登录控制器里先打印传入的密码,确认内容正确:

    User.findOne({ email: req.body.email }, function (err, user) {
      if (err) {
        return res.status(500).json({ title: 'An error occurred', error: err });
      }
      if (!user) {
        return res.status(401).json({ title: 'Login failed', error: { message: 'Invalid login credentials' } });
      }
      console.log('前端传入的密码:', req.body.password);
      console.log('数据库存储的哈希:', user.password);
      if (!bcrypt.compareSync(req.body.password, user.password)) {
        return res.status(401).json({ title: 'Login failed', error: { message: 'Invalid login credentials' } });
      }
      // ...后续逻辑
    })
    
  • 检查bcrypt版本兼容性
    不同版本的bcrypt可能存在哈希格式的细微差异,虽然compareSync一般会兼容旧格式,但如果你的项目里注册和登录环节用的bcrypt版本不一致,也可能导致比对失败。可以统一安装最新版本的bcrypt:

    npm uninstall bcrypt
    npm install bcrypt@latest
    

一般来说,字段长度不够导致哈希被截断是这个问题最常见的原因,建议你先从这个方向排查。

内容的提问来源于stack exchange,提问作者Miran Parkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:57:42