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 shoulde be using req.logout() to destroy the session in the browser.
I was having the same issue. Turned out that my version of passport wasn't compatible with Express 4.0. Just need to install an older version.
All examples here do a redirect after the req.session.destroy. But do realise that Express will create a new session instantly for the page you are redirecting to. In combination with Postman I found the strange behaviour that doing a Passport-Login right after the logout gives the effect that Passport is successful but cannot store the user id to the session file. The reason is that Postman needs to update the cookie in all requests for this group, and this takes a while. Also the redirect in the callback of the destroy does not help.
I solved it by not doing a redirect but just returning a json message.
I got an experience that, sometime it's doesn't work because you fail to to setup passport properly. For example, I do
vhost
, but on main app I setup passport like this which is wrong.app.js (why wrong ? please see blockqoute below)
actually, it must not be able to login, but I manage to do that because, I continue to do more mistake. by putting another passport setup here, so session form
app.js
available toapp.host.sub1.js
app.host.sub1.js
So, when I want to logout... it's not work because
app.js
was do something wrong by start initializepassport.js
beforeexpress-session.js
, which is wrong !!.However, this code can solved the issues anyway as others mention.
app.js
document also mention
So, resolved logout issue on my case by..
app.js
app.host.sub1.js
and now
req.logout();
is work now.Since you are using passport authentication which uses it's own session via the
connect.sid
cookie this simplest way of dealing with logging out is letting passport handle the session.This worked for me:
It makes sure that your page won't get stored in cache