bcrypt.compare() 在验证密码时总是返回 false
Posted
技术标签:
【中文标题】bcrypt.compare() 在验证密码时总是返回 false【英文标题】:bcrypt.compare() always returns false when verifying passwords 【发布时间】:2014-05-30 07:56:11 【问题描述】:我关注了来自 scotch.io 的this tutorial,了解如何使用 node.js 构建用户身份验证(顺便说一句,教程很棒)。但是,当调用verifyPassword(password)
来检查用户密码时,由于某种原因,该值总是返回为false。
我将 brcypt.js 和 sequelize.js 用于我的 express 项目。
模型用户的自定义方法:
classMethods :
setPassword : function(password)
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
,
instanceMethods:
verifyPassword: function(password)
return bcrypt.compare(password, this.password, function(err, result)
if (err) throw err;
return result;
);
这就是我创建新用户的方式:
User.find(where: email : email)
.complete(function(err, user)
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user)
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
else
User
.create(
email: email,
password: User.setPassword(password)
)
.complete(function(err, newUser)
if (err)
throw err;
return done(null, newUser)
)
);
验证密码:
User.find(where: email : email )
.complete(function(err, user)
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));
// if the user is found but the password is wrong
if (!user.verifyPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
// all is well, return successful user
return done(null, user);
);
我知道在 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;
);
);
我应该怎么做?
【问题讨论】:
【参考方案1】:bcrypt.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);
);
在创建时加密密码是钩子派上用场的地方,您可以使用 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
);
before create 将确保在将值插入数据库之前对其进行加密。
【讨论】:
感谢您的快速回复。我根据你的回答做了修改。但无论密码是否正确,用户始终可以登录。此外,结果始终返回为 false 我不知道如何使用 beforeCreate 方法。我是否也应该在模型中将其声明为 classMethod 并在我想创建用户时调用它?谢谢 嗨,我解决了这个问题。原来这是我的setter方法。我将其设置为: this.setDataValue('password', newPassword.toString().toLowercase) 等哈希都转换为小写。感谢您的帮助! 不,你在模型上声明了钩子,就像我在示例中提供的那样。很高兴您解决了您的问题。 天哪!我遇到了同样的问题。感谢您提及小写设置器。以上是关于bcrypt.compare() 在验证密码时总是返回 false的主要内容,如果未能解决你的问题,请参考以下文章
无论密码如何,Bcrypt-NodeJS compare() 都会返回 false
bcrypt.compare() 是异步的,这是不是一定意味着肯定会发生延迟? [复制]