I am using passport with passport-local-mongoose for register and login users.
This is the code I use to login users:
passport.use(new localStrategy({ usernameField: 'email' }, function(email, password, done) {
User.findOne({ email: email }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username or password.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect username or password.' });
}
return done(null, user);
});
}));
Everything works fun but user.validPassword. I define it in user model:
userSchema.methods.validPassword = function(password) {
// What should I write here?
};
Since hash password will be saved into database I do not know how to validate password.
For example this is one user saved into database{
"_id" : ObjectId("5901d55c30967512407cdcd0"),
"salt" : "7e76e1de50856c0a0e219c48609e0c86e8036bd4aa48e5161635f88dd19b695b",
"hash" : "eb78dcb7109454457b0709b6b49f322c69454930e3a6ca90621b1f38d4a068c46a34d0af8ba4f3cb3c3f9c8a30889f54028f182e1a038ab5d642e408117a93b34a519e594f62ea2209ef350f17d388e07476c021fdd66979e5752305b2f41571c830c4e03300cfbddce70443debee06d921900e1f7b9f024ea8d875553f01989e9267b01cc7e9da70f5ee39085527a55c8b6a9f5c7f21e07166797d5446322f52ec79c8e6bfd3e31d5f3953d86a13775da09f7ac3a5a85e5342cd35324bc66055030ca738fa657c50ec4368fe1fd4a26448b460996dc85ddebf90f92796f2b1adf9b905e0590efcadd8326053e354afcc144a155ca7ba1a0f1269cd2c5edec9ef4c643e5ca58310bf3283ed21bb94da6b22c113d19baf091f62bf1776fdcd4bca572cc114ec991d780c18524aad34988d0045f9a1d35e6cda4a6be337d7c8dce8256a240ecac9c7f4ac6c231a3c258f3660b5dd6daf4e67f878fbd9af9e52f9d36266828f564e6ac86f3aed98f7af0bb39017f6080e41cb49237bec6eae77253200750be14e53e79e3fc8d29a3a5cc774905e47bc8df6e5ae9f1b38d9ef738a7cc7890aba4bbea757c694df5faaeed2c692adcc9d8bb0242a5ced98c6a015f5b0b3b475b4a78767a1e9e3c6c9f1bc1be42a835f9e54de3ce223f6190ed457ea972ee4be6f506fd3995411d05247b7102c396c3a16b0d4c26664833d2224191cc",
"username" : "stve45",
"email" : "stebe@companycom",
"name" : "Steve",
"__v" : 0
}
I also use simple passport-local-authenticate.
Any help will be appreciate, thanks a lot.
If you are using passport-local-mongoose, it will create a salt and hash itself by taking your password. So that's why in your user schema you don't have to save the password field.
But the local strategy for passport-local-mongoose is quite different from normal passport local strategy. It is like
passport.use(new LocalStrategy(User.authenticate()));
This will check the entered password and will check it with the salt and hash.
The code you wrote is for normal local strategy. That should not use if you are using passport-local-mongoose.
This is how you should srialize and desirialize passport-local-mongoose:
passport.serializeUser(User.serializeUser());passport.deserializeUser(User.deserializeUser());
I assume you have a method for generating the salt and hash before saving.
In your validPassword method, you call the same method and compare the result from the user's password inout and compare it to what you have in the DB/ If it matches, then you are good.
As an alternative, there are libraries to manage this. I use bcrypt. See a sample here:
adminSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) {
return next();
}
// password changed so we need to hash it (generate a salt)
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) {
return next(err);
}else{
// hash the password using our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) { return next(err); }
// override the cleartext password with the hashed one
user.password = hash;
next();
});
}
});
});
adminSchema.methods.comparePassword = function(password, cb) {
console.log('comparing password');
bcrypt.compare(password, this.password, function(err, isMatch) {
cb(err, isMatch);
});
};
Here is an example code.Please note that the User.findOne() function is far from being complete.It's there just for you to see where this code stands with respect to yours and to give you an idea of what changes should be made.
passport.use('local.signup', new LocalStrategy({
usernameField:'email', //it can be email or whatever one chooses
passwordField:'password',
confirmField:'password',
passReqToCallback:true//here is the trick.u pass everything you want to do to a callback
},function (req,email, password, done) {
req.checkBody('email','Invalid e-mail address...').notEmpty().isEmail().normalizeEmail();//validate email
req.checkBody('password','Invalid password...').notEmpty().isLength({min:8});//validate pass to be min 8 chars but you can provide it with checking for capital letters and so on and so forth
var errors = req.validationErrors();
if(errors){
var messages = [];
errors.forEach(function (error) {
messages.push(error.msg)
});
return done(null, false, req.flash('error', messages))
}
User.findOne({ email: req.body.email }, function (err, user) {
// Make sure user doesn't already exist
if (user) return done(null, false, {message:'The email address you have
entered is already associated with another account.'
});