问题
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.
回答1:
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.
回答2:
The solution was if (!this.isModified('password')) return callback()
, shown below in full.
User.pre('save', function (callback) {
if (!this.isModified('password')) return callback()
this.password = bcrypt.hashSync(this.password, bcrypt.genSaltSync(10))
this.token = jwt.sign(this.email, process.env.JWT_SECRET)
callback()
})
This is because this fires more than once in the save process. So it was effectively hashing the password, then on the second round, hashing the hash.
来源:https://stackoverflow.com/questions/34360898/bcrypt-compare-always-returns-false