Soulrox
Soulrox

Reputation: 53

Passport deserializeUser never called

I am integrating Passport in my NodeJs APP and the signup works, the login in itself works but when redirecting directly after logging in my Session.Passport is empty again and deserializeUser is never called. Maybe someone sees where I made a mistake or has a clue to what I did wrong.

First my settings for Passport isinde my app.js:

app.use(session({ cookie: { maxAge: 18000 }, 
                  secret: cryptoSecret,
                  resave: false, 
                  saveUninitialized: true,
                  secure: false,
                  store: new memoryStore({checkPeriod: 86400000}),
                }));


app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use(passport.initialize());
app.use(passport.session()); 

My Local Strategy etc:


    // =========================================================================
    // passport session setup ==================================================
    // =========================================================================
    // required for persistent login sessions
    // passport needs ability to serialize and unserialize users out of session

    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        console.log('Serialize User');
        console.log(user);
        console.log('---------------------------------------');
        console.log(user._id);
        console.log('---------------------------------------');
        done(null, user._id);
    });

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        console.log('deserialize Important!');
        
        User.findById(id, function(err, user) {
            console.log(err);
            done(err, user);
        });
    });
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
            return done(null, user);
        });

    }));
}; 

And here is my Login-route:

router.post('/', cors(), passport.authenticate('local-login',  { failureRedirect : '/', failureFlash : true}), (req, res) => {    
    console.log('Login route!  Authenticated?:', req.isAuthenticated(), ' Session:' , req.session);
    req.logIn(req.session.passport.user, err => {
      if(err) {
        console.log(err);
      }
      res.redirect('/group');
    });
       
});

I get the same behaviour when using successRedirect instead of the res.redirect :/

Session directly after authenticating:

Session1

And my Session when redirecting:

Session2

I tracked it down to my deserializeUser-function not beeing called and read so many SO entrys and other sites with no change. Getting a bit frustrated atm. First of all thank you all for reading and helping. I appreciate every bit of information that might help me with this. I hope you all have a nice day :)

Upvotes: 2

Views: 1549

Answers (2)

mousto090
mousto090

Reputation: 2039

When you use passport.authenticate() as a route middleware you don't need req.logIn() because this middleware invokes req.login() automatically to establish a login session.

See req.login() in the passport docs.

console.log('Login route! Authenticated?:', req.isAuthenticated(), ' Session:' , req.session); shows the user is already authenticated.

I think the issue is that req.logIn() doesn't succeed and it overwrites the session, so you get different _expries time in /login and /group. Also try increasing the maxAge, you set it to 18 seconds

Try this

router.post('/login', cors(), passport.authenticate('local-login', { 
    failureRedirect: '/', failureFlash: true 
}), (req, res) => {
    // If this function gets called, authentication was successful.
    console.log('Login route!  Authenticated?:', req.isAuthenticated(), ' Session:', req.session);
    res.redirect('/group');
})

Upvotes: 0

Daniele Ricci
Daniele Ricci

Reputation: 15797

It seems that the problem is that session is not working, since after redirection the passport entry in your session is empty, it's normal that passport will not call deserializeUser.

Your comment seems to confirm the problem is in session system.

A minimal working session system could be:

const session = require("client-sessions");
const cookieParser = require("cookie-parser");
const express = require("express");

const app = express();

app.use(cookieParser());
app.use(session({ cookie: { ephemeral: true }, cookieName: "session", secret: "keyboardcat" }));

If neither this makes work your session system, I suggest you to check if something is making cookies not working in your setup.

Upvotes: 3

Related Questions