无论密码如何,Bcrypt-NodeJS compare()都会返回false

我知道这个问题已经被问了几次(就像在这里 , 在这里或那里 ,甚至是在Github上 ,但是没有一个答案真的对我有用 …

我正在尝试使用Mongoose和Passport为NodeJS应用程序开发身份validation,并使用Bcrypt-NodeJS来哈希用户的密码。

在我决定重构用户模式并使用bcrypt的asynchronous方法之前,所有工作都没有任何问题。 在创build新用户时,哈希仍然有效,但现在我无法validation存储在MongoDB中的哈希密码。

我知道什么?

  1. bcrypt.compare()总是返回false无论密码是否正确,以及任何密码(我试过几个string)。
  2. 密码只有一次散列(所以散列不重新散列)在用户的创build。
  3. 给比较方法的密码和散列是正确的顺序。
  4. 密码和哈希types是“string”。
  5. 存储在数据库中时不会截断哈希(长度为60个字符的string)。
  6. 数据库中提取的哈希与用户创build时存储的哈希相同。

用户架构

有些领域已经被剥离,以保持清楚,但我保留了相关的部分。

 var userSchema = mongoose.Schema({ // Local authentication password: { hash: { type: String, select: false }, modified: { type: Date, default: Date.now } }, // User data profile: { email: { type: String, required: true, unique: true } }, // Dates lastSignedIn: { type: Date, default: Date.now } }); 

密码哈希

 userSchema.statics.hashPassword = function(password, callback) { bcrypt.hash(password, bcrypt.genSaltSync(12), null, function(err, hash) { if (err) return callback(err); callback(null, hash); }); } 

密码比较

 userSchema.methods.comparePassword = function(password, callback) { // Here, `password` is the string entered in the login form // and `this.password.hash` is the hash stored in the database // No problem so far bcrypt.compare(password, this.password.hash, function(err, match) { // Here, `err == null` and `match == false` whatever the password if (err) return callback(err); callback(null, match); }); } 

用户authentication

 userSchema.statics.authenticate = function(email, password, callback) { this.findOne({ 'profile.email': email }) .select('+password.hash') .exec(function(err, user) { if (err) return callback(err); if (!user) return callback(null, false); user.comparePassword(password, function(err, match) { // Here, `err == null` and `match == false` if (err) return callback(err); if (!match) return callback(null, false); // Update the user user.lastSignedIn = Date.now(); user.save(function(err) { if (err) return callback(err); user.password.hash = undefined; callback(null, user); }); }); }); } 

这可能是我犯的一个“简单”的错误,但几个小时后我却找不到任何错误……请问你有什么想法让这个方法奏效,我很乐意阅读它。

感谢你们。

编辑:

运行这段代码时,match实际上等于true 。 所以我知道我的方法是正确的。 我怀疑这与散列在数据库中的存储有关,但是我真的不知道什么会导致这个错误发生。

 var pwd = 'TestingPwd01!'; mongoose.model('User').hashPassword(pwd, function(err, hash) { console.log('Password: ' + pwd); console.log('Hash: ' + hash); user.password.hash = hash; user.comparePassword(pwd, function(err, match) { console.log('Match: ' + match); }); }); 

编辑2(和解决scheme):

我把它放在那里,以防某天某些事对他有帮助。

我在我的代码中发现了错误,这是在用户注册期间发生的(实际上是我没有发布的唯一一段代码)。 我哈希的user.password对象,而不是user.password.plaintext

只有通过将我的依赖关系从“brcypt-nodejs”更改为“bcryptjs”,才能find错误,因为bcryptjs在被要求散列对象时抛出一个错误,而brcypt-nodejs只是将对象散列化,就好像它是一个string。

bcrypt.hash()有3个参数…你有4个由于某种原因。

代替

 bcrypt.hash(password, bcrypt.genSaltSync(12), null, function(err, hash) { 

它应该是

 bcrypt.hash(password, bcrypt.genSaltSync(12), function(err, hash) { 

由于您只是在用户创build期间进行哈希,因此您可能没有正确地进行哈希处理。 您可能需要重新创build用户。