bcrypt.compare() 在验证密码时总是返回 false [英] bcrypt.compare() always returns false when verifying passwords

查看:37
本文介绍了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 用于我的 express 项目.

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 似乎是异步的,你应该扩展你的比较函数来接受回调.

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

before create 将确保在将值插入数据库之前对其进行加密.

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆