Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
337 views
in Technique[技术] by (71.8m points)

javascript - Bcrypt compare always returns false

bcrypt.compare() always comes back false with this code in the user model. This is with bcrypt-nodejs.

User.pre('save', function (callback) {
  this.password = bcrypt.hashSync(this.password, bcrypt.genSaltSync(10))
  this.token = jwt.sign(this.email, process.env.JWT_SECRET)
  callback()
})

User.methods.verifyPassword = function ( password ) {
  const self = this

  return Q.Promise( (resolve, reject) => {
    bcrypt.compare( password, self.password, (error, isMatch) => {
      if (error) reject( new Error("Error checking user password."))
      resolve(isMatch)
    })
  })
}

I can see that a hash appears in the database. I can see the that right password comes into the verifyPassword function.


EDIT: The issue seems to be that .pre('save', ... occurs twice in a row. So the newly hashed password gets hashed again.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's a working version of your code. I am not sure what all is happening behind the scenes with your methods so I made that part up.

To prove it works add this to a file called index.js and run it with "node index.js".

It will output this:

We got a match! true or false? true

Here's the code.

var bcrypt = require('bcrypt');
var Q = require('Q');
var salt = bcrypt.genSaltSync(10);


process.env.JWT_SECRET = 'Much_Secretive,_Such_Obscure';

function SuperUser () {
  this.pre = function (password, callback) {
    this.password = bcrypt.hashSync(password, salt);
    callback.call(this, password);
  };
  this.methods = {};
}

var User = new SuperUser();

User.methods.verifyPassword = function ( password ) {
  const self = this;

  return Q.Promise( (resolve, reject) => {
    bcrypt.compare( password, self.password, (error, isMatch) => {
      if (error) reject( new Error("Error checking user password."));
      console.log("We got a match! true or false? " + isMatch);
      resolve(isMatch);
    });
  });
};

User.pre('save', function (password) {
  this.methods.verifyPassword.call(this,password);
});

Without seeing your full implementation it's hard to know for sure, but there is probably a reference to 'this' that is not the 'this' you would expect it to be.

I use function.call a couple times to get around that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...