I have been working on implementing user log-in using passport-local and express. While I have successfully managed to achieve log-ins with usernames, I find them hard to remember and not ideal for user authentication. Therefore, I attempted to customize the provided LocalStrategy from the passport-local page to authenticate users via email instead of usernames. However, the modified code does not function as expected.
The email strategy I tried is as follows:
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' });
}
});
});
}));
This email strategy was derived from the following username 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' });
}
});
});
}));
While the strategy for usernames works flawlessly, the one for email encounters issues. I even used console.log() in both strategies to observe their outputs. The username strategy returns all user information correctly, but the email strategy returns
false
. I am unsure of why this discrepancy occurs and none of the solutions I found have resolved it.
An alternative solution recommended elsewhere suggested utilizing the
findOne({email: email}, function(err, user){
});
approach to search for a user by email, but that also proved unsuccessful.
Below is the Jade file I implemented for user input:
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
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);
};
I am puzzled by the unexpected behavior when attempting to use email for authentication. Additionally, how can I confirm the email address after a user registers?