Node.js 验证密码时,bcrypt.compare()始终返回false
我从scotch.io了解了如何使用node.js构建用户身份验证(顺便说一下,这是一个很棒的教程)。但是,当调用Node.js 验证密码时,bcrypt.compare()始终返回false,node.js,authentication,passport.js,bcrypt,sequelize.js,Node.js,Authentication,Passport.js,Bcrypt,Sequelize.js,我从scotch.io了解了如何使用node.js构建用户身份验证(顺便说一下,这是一个很棒的教程)。但是,当调用verifyPassword(password)检查用户密码时,由于某些原因,该值始终返回为false 我在express项目中使用brcypt.js和sequelize.js 模型用户的自定义方法: 以下是我创建新用户的方式: 验证密码: 我知道在bcrypt中使用异步模式更好,但当我尝试以下操作时,它总是给我“未定义密码”: setPassword : function(pass
verifyPassword(password)
检查用户密码时,由于某些原因,该值始终返回为false
我在express项目中使用brcypt.js和sequelize.js
模型用户的自定义方法:
以下是我创建新用户的方式:
验证密码:
我知道在bcrypt中使用异步模式更好,但当我尝试以下操作时,它总是给我“未定义密码”:
setPassword : function(password) {
return bcrypt.genSalt(10, function(err, salt) {
if (err) return err;
return bcrypt.hash(password, salt, function(err, hash) {
if (err) return err;
return hash;
});
});
}
我应该怎么做呢?bcrypt.compare似乎是异步的,您应该扩展compare函数以进行回调 您可以对setPassword执行相同的操作,但必须在回调中进行创建。您现在正在同步事务中使用它,所以它必须是一个同步函数 你可以这样做:
classMethods : {
setPassword : function(password, callback) {
// Pseudo, i don't actually know the bcrypt api
return bcrypt.hash(password, bcrypt.genSaltSync(8), callback);
}
},
instanceMethods: {
verifyPassword: function(password, callback) {
bcrypt.compare(password, this.password, callback);
}
}
Uset.setPassword(password, function (err, password) {
if (err) return done(err);
User.create({
email: email,
password: password
}).done(done);
});
user.verifyPassword(password, function (err, result) {
if (err || result) return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, user);
});
然后将接口代码重写为:
classMethods : {
setPassword : function(password, callback) {
// Pseudo, i don't actually know the bcrypt api
return bcrypt.hash(password, bcrypt.genSaltSync(8), callback);
}
},
instanceMethods: {
verifyPassword: function(password, callback) {
bcrypt.compare(password, this.password, callback);
}
}
Uset.setPassword(password, function (err, password) {
if (err) return done(err);
User.create({
email: email,
password: password
}).done(done);
});
user.verifyPassword(password, function (err, result) {
if (err || result) return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, user);
});
在创建时加密密码是钩子派上用场的地方,您可以在保存密码之前使用beforeCreate钩子加密密码,而不是自己处理加密
User.beforeCreate(function (model, done) {
bcrypt.hash(model.password, bcrypt.genSaltSync(8), function (err, password) {
if (err) return done(err);
model.password = password;
done();
});
});
User.create({
email: email,
password: password // Unencrypted
});
然后,“创建前”将确保在将值插入数据库之前对其进行加密。感谢您的快速回复。我根据你的回答做了改变。但无论密码是否正确,用户都可以登录。另外,结果总是以False形式返回。我不知道如何使用beforeCreate方法。我是否应该在模型中将其声明为classMethod,并在创建用户时调用它?谢谢,我解决了这个问题。原来是我的setter方法。我将其设置为:this.setDataValue('password',newPassword.toString().toLowercase),因此哈希都转换为小写。谢谢你的帮助!不,您可以在模型上声明钩子,就像我在示例中提供的那样。很高兴你解决了你的问题。天哪!我也有同样的问题。谢谢你提到小写setter。
User.beforeCreate(function (model, done) {
bcrypt.hash(model.password, bcrypt.genSaltSync(8), function (err, password) {
if (err) return done(err);
model.password = password;
done();
});
});
User.create({
email: email,
password: password // Unencrypted
});