node.js - bcrypt.compare() 验证密码时始终返回 false

标签 node.js authentication passport.js bcrypt sequelize.js

我关注了this tutorial来自 scotch.io 关于如何使用 node.js 构建用户身份验证(顺便说一句,这是一个很棒的教程)。但是,当调用 verifyPassword(password) 来检查用户密码时,由于某种原因,该值总是返回 false。

我正在为我的express项目使用brcypt.js和sequelize.js。

模型用户的自定义方法:

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;
        });
    });
 }

我应该做什么?

最佳答案

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);
  }
}

然后将您的接口(interface)代码重写为:

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);
});

在创建时加密密码是钩子(Hook)派上用场的地方,您可以使用 beforeCreate 钩子(Hook)在保存密码之前对其进行加密,而不是自己处理加密。

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
});

创建之前将确保该值在插入数据库之前已加密。

关于node.js - bcrypt.compare() 验证密码时始终返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23092581/

相关文章:

c# - 如何从 cookie 中检索 OpenID Connect 身份 token

javascript - 巢JS : Auth guard flow

javascript - Passportjs 获取身份验证错误消息

oauth - 在passport.js 中为OAuth 策略动态指定重定向URL 的最佳方法是什么?

javascript - Windows 版 Node 中的 Shebang

mysql - heroku Sequelize : command not found

javascript - node.js 中的 require() 是如何工作的?

javascript - 生产环境中的node.js

c# - WCF UserNamePasswordValidator 是否需要检查 PrimaryIdentity.IsAuthenticated?

ios - 401错误-使用AFNetworking AFHTTPClient和Tastypie进行基本身份验证