简体   繁体   English

验证密码时,bcrypt.compare()始终返回false

[英]bcrypt.compare() always returns false when verifying passwords

I followed this tutorial from scotch.io on how to build user authentication using node.js (great tutorial by the way). 我遵循了scotch.io的本教程 ,内容涉及如何使用node.js构建用户身份验证(顺便说一句,很棒的教程)。 However, when verifyPassword(password) is called to check user password, the value is always returned as false for some reason. 但是,当verifyPassword(password)来检查用户密码时,由于某种原因,该值始终返回为false。

I'm using brcypt.js and sequelize.js for my express project. 我为我的快递项目使用了brcypt.js和sequelize.js。

custom methods for model User: 模型用户的自定义方法:

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;

          });
    }

}   

this is how i create a new user: 这就是我创建新用户的方式:

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


         }

}); 

verifying password: 验证密码:

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

I know its better to use async mode in bcrypt but it always gives me "password undefined" when I try something like this: 我知道最好在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;
        });
    });
 }

what should I do instead? 我该怎么办?

bcrypt.compare appears to be asynchronous, you should extend your compare function to take a callback. bcrypt.compare似乎是异步的,您应该扩展您的compare函数以进行回调。

You could do the same for setPassword but you'll have to do your create inside the callback. 您可以对setPassword进行相同的操作,但必须在回调内部进行创建。 You're using it in a synchronous matter right now so it will have to be a synchronous function. 您现在正在同步事务中使用它,因此它必须是同步函数。

You could do something like: 您可以执行以下操作:

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

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. 钩子很方便,可以在创建时对密码进行加密,而不是自己进行加密,您可以使用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
});

The before create will then make sure the value is encrypted before it is inserted to the database. 然后,before创建将确保在将值插入数据库之前对其进行加密。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM