Reputation: 23
I am using bcrypt (v2.0.1) in a MERN project (Node v8.10.0) to store user passwords in MongoDB using Mongoose. The hash function:
SellerSchema.pre('save', function (next) {
var user = this;
bcrypt.hash(user.password, 10, function (err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
The authenticate part:
SellerSchema.statics.authenticate = function (email, password, callback) {
Seller.findOne({ email: email })
.exec(function (error, user) {
if (error) return callback(error);
else if (!user) {
var err = new Error('User not found.');
err.status = 401;
return callback(err);
}
bcrypt.compare(password, user.password).then(function (result){
if (result == true) {
return callback(null, user);
} else {
return callback();
}
});
});
};
The login route:
router.post('/login', function(req, res, next) {
if (req.body.email && req.body.password){
Seller.authenticate(req.body.email,req.body.password,function(error,user) {
if (error || !user) {
console.log("this "+error);
var err = new Error('Wrong email or password.'); // logged everytime the compare result was false
err.status = 401;
return next(err);
} else {
res.json(user);
}
});
} else {
var err = new Error('Email and password are required.');
err.status = 401;
return next(err);
}
});
When signing up new users, the hash is stored fine & logging in using the plain-text does passes the compare() for few times, but returns false after that.
If I signup a new user and login, it works again for sometime and then starts returning false. For example: I am still able to login a user registered hours ago (10-15 compares) but not able to login a user created minutes ago (after 1-2 compares)
Using Node : 8.10.0 , OS: Ubuntu 18.04
Upvotes: 1
Views: 713
Reputation: 2134
your pre('save')
middleware is updating password every time you save object.To stop this use isModified
function of mongoose like below:
SellerSchema.pre('save', function(next) {
if (this.isModified('password')) { // check if password is modified then has it
var user = this;
bcrypt.hash(user.password, 10, function(err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
});
} else {
next();
}
});
Upvotes: 3