So I'm using passport-local and express to handle user log-in. So far I have been able to get a successful log-in while using usernames, but usernames are hard to remember and I personally don't think they should be used for handling users, so I tried modifying the sample Strategy provided on the passport-local page to confirm users via email, but the code doesn't work.
The strategy I have for emails is:
passport.use(new LocalStrategy(function(email, password, done) { User.findOne({ email: email }, {}, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Unknown user ' + e }); } user.comparePassword(password, function(err, isMatch) { if (err) return done(err); if(isMatch) { return done(null, user); } else { return done(null, false, { message: 'Invalid password' }); } }); }); }));
And It's derived from this strategy:
//The login strategy passport.use(new LocalStrategy(function(username, password, done) { User.findOne({ username: username }, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Unknown user ' + username }); } user.comparePassword(password, function(err, isMatch) { if (err) return done(err); if(isMatch) { return done(null, user); } else { return done(null, false, { message: 'Invalid password' }); } }); }); }));
So the username strategy works perfectly fine, but the email one is not. I even left a console.log() in both the username and email strategy to see what the strategies were returning. The Username strategy returns all information on the user, while the email strategy returns
false
. I have no idea why the site is doing this, and none of the solutions I've seen so far work.
One solution I've seen on another post suggested that I just use the
findOne({email: email}, function(err, user){ });
option to login with the email to find the user, but it hasn't been working at all.
Here is the Jade file I use to take input from the user:
extends layout block content h1 Login form(action= '/login', method='post') p Email br input#email(type='text',value='',placeholder='@',name='email') p Password br input#password(type='password',value='',placeholder='Password',name='password') input(type='submit') Submit
And here is the POST input:
// POST /login // This is an alternative implementation that uses a custom callback to // acheive the same functionality. exports.postlogin = function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) { return next(err) } if (!user) { req.session.messages = [info.message]; return res.redirect('/login') } req.logIn(user, function(err) { if (err) { return next(err); } return res.redirect('/'); }); })(req, res, next); };
What the heck is going on here? With email it should be working perfectly. Also since I'm asking a question anyway, how do I confirm the email after somebody had registered?
Configure Strategy The local authentication strategy authenticates users using a username and password. The strategy requires a verify callback, which accepts these credentials and calls done providing a user.
To sum it up, passport. serializeUser() saves the user inside the session which was earlier created by express-session middleware. Once the user is saved inside the session, the session itself also will get stored inside the database (only if we opt to).
You can reset or change passwords using 2 simple functions in passport-local-mongoose. They are setPassword function and changePassword functions. Normally setPassword is used when the user forgot the password and changePassword is used when the user wants to change the password.
It seems to me you just changed the name of the argument in the LocalStrategy callback to "email". Passport doesn't automagically know that the field is named email though, you have to tell it.
By default, LocalStrategy expects to find credentials in parameters named username and password. If your site prefers to name these fields differently, options are available to change the defaults.
passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'passwd' }, function(username, password, done) { // ... } ));
Source
If you are new to NestJs and wondering how to achieve the above. You can pass the config options in the super()
method like this:
super({ usernameField: 'email', passwordField: 'password' })
source
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With