Charlie Fish Charlie Fish - 4 months ago 27
Node.js Question

Node.js Passport not calling next function

I'm building an application using Node that uses Passport.js to handle user login using a local database.

So I have the following code that gets called when a user goes to /profile. After successfully logging in the user gets redirected to /profile. Which does happen according to morgan.

app.get('/profile', passport.authenticate('local-login', { session : false, failureRedirect : '/login' }), function(req, res) {
console.log("testnow");
res.render('profile.ejs', {
user : req.user // get the user out of session and pass to template
});
});


My local-login code is the following.

passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);

// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash

// if the user is found but the password is wrong
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata

// all is well, return successful user
console.log("testdone");
return done(null, user);
});
}));


When testing the code I login and get redirected to profile for a split second. The console prints "testdone" which is in my local-login code BUT doesn't print "testnow" as it is expected to. Meaning the second function in my /profile get method never seems to get called even tho local-login is calling the next function.

So from the end users standpoint you login (behind the scenes you get redirected to /profile for a split section) and /profile redirects you back to /login.

Any ideas on how to fix this so the second function in my /profile get method actually gets called?

Thanks so much in advance. I would also be more then happy to provide any additional information to help figure this out.

Answer

passport.authenticate() is meant to handle the actual authentication; in other words, to take the login credentials and pass them to the strategy. It's not meant to pass along requests if they are already authenticated, which is what you're trying to use it for.

Instead, you want to use something like connect-ensure-login to guard routes for which a user has to be logged in.

See also this Passport example project.

Comments