密码包含数字时,bcrypt比较返回false

时间:2014-11-20 16:33:35

标签: javascript node.js express bcrypt

我使用node-bcrypt和PostgreSQL(通过Sequelizejs来哈希并保存密码。

用户的密码在beforeValidate挂钩中进行哈希处理,如下所示:

beforeValidate: function(user, model, cb) {
        bcrypt.hash(user.password, 10, function(err, hash) {
          if ( err ) { throw err; }
          user.password = hash;
          cb(null, user);
        });
      }

存储哈希的User模型中的列定义为:

password: { type: DataTypes.STRING, allowNull: false }

当用户登录时(我使用Passport进行身份验证),该功能如下所示:

passport.use(new LocalStrategy(function(username, password, done) {
    models.User.find({ username: username }).then(function(retrievedUser) {
      if ( !_.isEmpty(retrievedUser) ) {
        retrievedUser.verifyPassword(password, function(err, result) {
          if ( err || !result ) {
            return done(null, false, { message: 'Incorrect password.' });
          } else {
            return done(null, retrievedUser);
          }
        });
      } else {
        return done(null, false, { message: 'User could not be found at that username.' });
      }
    }).catch(function(err) {
      return done(err);
    });
  }));

正确检索用户。

比较,在用户模型中定义:

instanceMethods: {
      verifyPassword: function(password, cb) {
        bcrypt.compare(password, this.password, cb);
      }
    }

如果密码只包含字母和/或符号,则验证通过正常。但是,任何带数字的密码都不会通过比较。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

在你的beforeValidate函数中,你传递的是生成盐所需的盐,将该函数更改为

beforeValidate: function(user, model, cb) {
    var salt = bcrypt.genSalt(10);
    bcrypt.hash(user.password, salt, function(err, hash) {
      if ( err ) { throw err; }
      user.password = hash;
      cb(null, user);
    });
  }

答案 1 :(得分:2)

嗯,令人尴尬(并且有些人怀疑),这与Bcrypt完全无关。

在我的身份验证功能中,我试图使用以下内容获取相应的用户:

models.User.find({ username: username })

但是,应该在where字段中指定查询,如下所示:

models.User.find({
   where: { username: username }
})

这导致身份验证方法始终与数据库中第一个用户的密码进行比较(默认情况下,在未指定where字段时返回)。因此,它看起来很有效,因为第一个用户的字母密码始终有效,但没有后续密码有效(实际上,即使是只有字母的密码也会因其他用户而失败)。