Paulie Paulie - 4 months ago 13
Node.js Question

Nodejs and PassportJs: Redirect middleware after passport.authenticate not being called if authentication fails

I have no login page but rather I have a login form that appears on every page. I want to redirect user back to the same page they were on regardless of whether authentication was successful (with appropriate flash messages)

Take the following code:'/login', validateLogin, passport.authenticate('local-login'), function(req, res) {

var redirectUrl = '/';

if( > 0){
redirectUrl =;

console.log("THIS IS ONLY CALLED IF passport.authenticate() IS SUCCESSFUL");

I only see the final middleware above being called if authentication is passed. If it fails then passport appears to be redirecting me to /login in the form of a get request. In my app this page doesn't exist.

If I pass an additional options object as a parameter in the passport authenticate function then this works:'/login', validateLogin, passport.authenticate('local-login', {

successRedirect : '/', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page. THIS IS JUST FOR TESTING TO SEE IF THE REDIRECT ON FAIL WORKS.
failureFlash : true, // allow flash messages



But in doing this I lose the ability to choose where to redirect the user to. It seems that passport takes control over where the user is redirected to if authentication fails. How can I fix this? Or is it a bug? Must passport authenticate be the last middleware in the chain if authentication fails?

This is my local strategy function call:


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

console.log("IN PASSPORT");

if(email.length == 0 || password.length == 0){

console.log("FIELDS ARE EMPTY");
return done(null, false, req.flash('loginMessage', 'Fill in all values.'));


// 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({ '' : email }, function(err, user) {
// if there are any errors, return the error before anything else

if (err){
return done(err);
console.log("db err");
// if no user is found, return the message
if (!user){
console.log("not user");
return done(null, false, req.flash('loginMessage', 'Incorrect details.')); // 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)){
console.log("invalid pw");
return done(null, false, req.flash('loginMessage', 'Incorrect details.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
console.log("All OK");
return done(null, user);



You could use a custom authentication callback as described in the last paragraph there'/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    // Redirect if it fails
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      // Redirect if it succeeds
      return res.redirect('/users/' + user.username);
  })(req, res, next);