bcrypt.compare() always returns false when verifying passwords

我只是一个虾纸丫 提交于 2019-12-12 04:49:58

问题


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.

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

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:

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?


回答1:


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

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.

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.

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.



来源:https://stackoverflow.com/questions/23092581/bcrypt-compare-always-returns-false-when-verifying-passwords

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!