I am having trouble getting my system to log out with PassportJS. It seems the logout route is being called, but its not removing the session. I want it to return 401, if the user is not logged in in specific route. I call authenticateUser to check if user is logged in.
Thanks a lot!
/******* This in index.js *********/ // setup passport for username & passport authentication adminToolsSetup.setup(passport); // admin tool login/logout logic app.post("/adminTool/login", passport.authenticate('local', { successRedirect: '/adminTool/index.html', failureRedirect: '/', failureFlash: false }) ); app.get('/adminTool/logout', adminToolsSetup.authenticateUser, function(req, res){ console.log("logging out"); console.log(res.user); req.logout(); res.redirect('/'); }); // ******* This is in adminToolSetup ******** // Setting up user authentication to be using user name and passport as authentication method, // this function will fetch the user information from the user name, and compare the password for authentication exports.setup = function(passport) { setupLocalStrategy(passport); setupSerialization(passport); } function setupLocalStrategy(passport) { passport.use(new LocalStrategy( function(username, password, done) { console.log('validating user login'); dao.retrieveAdminbyName(username, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Incorrect username.' }); } // has password then compare password var hashedPassword = crypto.createHash('md5').update(password).digest("hex"); if (user.adminPassword != hashedPassword) { console.log('incorrect password'); return done(null, false, { message: 'Incorrect password.' }); } console.log('user validated'); return done(null, user); }); } )); } function setupSerialization(passport) { // serialization passport.serializeUser(function(user, done) { console.log("serialize user"); done(null, user.adminId); }); // de-serialization passport.deserializeUser(function(id, done) { dao.retrieveUserById(id, function(err, user) { console.log("de-serialize user"); done(err, user); }); }); } // authenticating the user as needed exports.authenticateUser = function(req, res, next) { console.log(req.user); if (!req.user) { return res.send("401 unauthorized", 401); } next(); }
You can call req. logout() which will invalidate the session on the server side. So even if the user sends a cookie, the cookie id will no longer be found in the session store, so the user will no longer be able to access resources which require authentication.
js controller to include a logout method. Remember to put it AFTER you require all the middleware: // LOGOUT app. get('/logout', (req, res) => { res.
Passport uses serializeUser function to persist user data (after successful authentication) into session. The function deserializeUser is used to retrieve user data from session and perform some condition-based operations.
The serializeUser is the one which determines which data in the user object is. to be stored in the session. The first argument of deserializeUser corresponds to the key of user object.
Brice’s answer is great, but I still noticed an important distinction to make; the Passport guide suggests using .logout()
(also aliased as .logOut()
) as such:
app.get('/logout', function(req, res){ req.logout(); res.redirect('/'); //Can fire before session is destroyed? });
But as mentioned above, this is unreliable. I found it behaved as expected when implementing Brice’s suggestion like this:
app.get('/logout', function (req, res){ req.session.destroy(function (err) { res.redirect('/'); //Inside a callback… bulletproof! }); });
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With