本文介绍了验证密码时,bcrypt.compare()始终返回false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了scotch.io的本教程关于如何使用node.js构建用户身份验证的方式(顺便说一句,很棒的教程).但是,当调用verifyPassword(password)来检查用户密码时,由于某种原因,该值始终返回为false.

I followed this tutorial from scotch.io on how to build user authentication using node.js (great tutorial by the way). However, when verifyPassword(password) is called to check user password, the value is always returned as false for some reason.

我在我的快递项目中使用了brcypt.js和sequelize.js.

I'm using brcypt.js and sequelize.js for my express project.

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中使用异步模式,但是当我尝试这样的操作时,它总是给我未定义密码":

I know its better to use async mode in bcrypt but it always gives me "password undefined" when I try something like this:

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函数以进行回调.

bcrypt.compare appears to be asynchronous, you should extend your compare function to take a callback.

您可以对setPassword进行相同的操作,但是必须在回调内部进行创建.您现在正在同步事务中使用它,因此它必须是同步函数.

You could do the same for setPassword but you'll have to do your create inside the callback. You're using it in a synchronous matter right now so it will have to be a synchronous function.

您可以执行以下操作:

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

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

And then rewrite your interfacing code to something like:

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钩子在保存密码之前对其进行加密.

Encrypting passwords on create is where hooks come in handy, instead of handling the encrypting yourself you could use a beforeCreate hook to encrypt the password before it gets saved.

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

然后,创建之前,将确保将该值加密,然后再将其插入数据库.

The before create will then make sure the value is encrypted before it is inserted to the database.

这篇关于验证密码时,bcrypt.compare()始终返回false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 18:28