Search code examples
node.jsexpresscookiespassport.jsexpress-session

req.session.destroy and passport logout aren't destroying cookie on client side


I'm trying to destroy the cookie on the client side but can't seem to figure out how to. I've tried the few ways that passport and some answers on SO provided but I'm at a loss as to how to clear the actual cookie.

My code so far is:

app.get('/logout', function (req, res){
    sessionStore.destroy(req.sessionID, (err) =>{
        if(err)console.log(err);
        req.logout();
        req.session.destroy(function (err) {
            if(err) console.log(err);
            res.status(200).json({message : 'User Logged Out'});
        });

    });

});

I have also tried the req.logOut(); method.


Solution

  • req.logout does not clear the session but instead it clears the login information from the session. An example from my session store after login:

    > db.sessions.find().pretty();
    {
      "_id" : "LkuoFL_cwkvNO3foD_k0zQYADevcdwW6",
      "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"test\"}}",
      "expires" : ISODate("2018-06-05T17:31:54.631Z")
    }
    

    Here you can see that passport.user in the session JSON holds the value I returned from serializeUser (the username). After calling req.logout the session store still holds the session but the serialized user information is missing, ie. I'm not logged in anymore:

    > db.sessions.find().pretty();
    {
      "_id" : "LkuoFL_cwkvNO3foD_k0zQYADevcdwW6",
      "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"passport\":{}}",
      "expires" : ISODate("2018-06-05T17:32:02.391Z")
    }
    

    If I change my logout route handler to this:

    app.post('/logout', (req, res) => {
      req.logout();
      req.session.destroy((err) => res.redirect('/'));
    });
    

    I can see that after logout the session above has disappeared but a new one was created because I landed on the front page and it starts a new session:

    > db.sessions.find().pretty();
    {
      "_id" : "KIX2rypzvpRdqW7VlzO8B8W-FMXwffGT",
      "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"}}",
      "expires" : ISODate("2018-06-05T17:38:01.136Z")
    }
    

    Also the connect.sid cookie in the browser now holds the new session key.

    Now add the clearCookie. With logout handler like this one:

    app.post('/logout', (req, res) => {
      req.logout();
      req.session.destroy((err) => {
        res.clearCookie('connect.sid');
        // Don't redirect, just print text
        res.send('Logged out');
      });
    });
    

    the session store is empty after clicking the logout button (notice, that no further requests are performed in the example):

    > db.sessions.find().pretty();
    > 
    

    and the response headers of the logout request show a cleared cookie:

    Set-Cookie: connect.sid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT

    Now, if no further requests are performed to the server (new ones may start a new session even if not logged in) you should not see connect.sid cookie in the browse developer tools anymore.