【问题标题】:bcrypt.compare() always returns false when verifying passwordsbcrypt.compare() 在验证密码时总是返回 false
【发布时间】: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;
        });
    });
 }

我应该怎么做?

【问题讨论】:

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


    【解决方案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) 等哈希都转换为小写。感谢您的帮助!
    • 不,你在模型上声明了钩子,就像我在示例中提供的那样。很高兴您解决了您的问题。
    • 天哪!我遇到了同样的问题。感谢您提及小写设置器。
    猜你喜欢
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2019-05-27
    • 2021-09-29
    • 2015-01-05
    相关资源
    最近更新 更多