当密码包含数字时,bcrypt比较返回false
我使用节点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); }); }
用户模型中存储哈希的列被定义为:
password: { type: DataTypes.STRING, allowNull: false }
当用户login时(我使用Passport进行身份validation),该函数如下所示:
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); } }
如果密码只包含字母和/或符号,validation通过就可以了。 但是,任何使用数字的密码都不能通过比较。 有任何想法吗?
在你的beforeValidate
函数中,你传递10作为你需要产生盐的盐,改变这个函数
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); }); }
那么,令人尴尬的(和一些人怀疑),这是完全无关Bcrypt。
在我的身份validationfunction中,我试图使用以下方法获取相应的用户:
models.User.find({ username: username })
但是,查询应该已经在where
字段中指定,如下所示:
models.User.find({ where: { username: username } })
这导致身份validation方法始终与数据库中第一个用户的密码进行比较(当没有指定where
字段时,默认返回)。 因此,它似乎工作,因为第一个用户的只有密码的密码总是工作,但没有以下的密码工作(实际上,即使只有一个字母的密码会失败的其他用户)。