Fahid Mohammad Fahid Mohammad - 3 months ago 34
Javascript Question

PassportJS Session doesn't working with custom callback

The below custom call back for passport.js doesn't seems to work, no mater what i do.

app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, users, info) {
console.log(users);
if (user === false) {
console.log('Failed!');
} else {
res.redirect('/');
}
})(req, res, next);
});


The same if i change it to like below all works as expected.

app.post("/login"
,passport.authenticate('local',{
successRedirect : "/",
failureRedirect : "/login",
})
);


Also I've noticed when using custom callback even the
passport.serializeUser
and
passport.deserializeUser
also not getting invoked by passport.js.

Is this any sort of a bug or am i doing something wrong here ??

My Local-Strategy:

passport.use('local-sigin',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('Passport Strategy Sign in:');
// 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' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done({status:'ERROR',message:'Something went wrong!'});

// if no user is found, return the message
if (!user)
return done({status:'ERROR',message:'No user found.'}, false);

// if the user is found but the password is wrong
if (!user.validPassword(password))
return done({status:'ERROR',message:'Oops! Wrong password.'}, false);

// all is well, return successful user
return done({status:'OK',message:'Login success.'}, user);
});
}));

Answer

I am guessing that by 'doesn't work' you mean to say that the user is never being logged in.

Firstly, your local strategy is named 'local-sigin' however on a POST to '/login' you are invoking the 'local' strategy, which presumably doesn't exist:

passport.use('local', new LocalStrategy({

Change the name of your strategy to be consistent (or vice versa!):

passport.authenticate('local'

Secondly, your 'local' authentication callback has a parameter users (plural) but you are trying to access user (singular) within its body, meaning user is undefined and user === false is false under strict equality:

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
                                            // ^^^^
    console.log(user);
    if (!user) {
      console.log('Failed!');
    } else {
      res.redirect('/');
    }
  })(req, res, next);
});

And finally, you are never logging the user in when authentication is successful. Creating a session for a user is not automatic, you must call req#login:

Passport exposes a login() function on req (also aliased as logIn()) that can be used to establish a login session.

Let's add that to your authentication callback:

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    console.log(user);
    if (!user) {
      console.log('Failed!');
    } else {
      req.login(user, function (err) {
          if(err) {
            console.log(err);
            return;
          }
          res.redirect('/');
      });
    }
  })(req, res, next);
});

Take a look at the Passport docs, they explain in a good amount of detail how these processes work and how to implement them.

Comments