Express.js Session storage persistence issue

Viewed 129

I'm having a really odd issue with session storage using mongoDB and passport.

When a user logs in, the session is created and passed to mongo as expected as well as the passport id.

{
    "_id" : "GEEFIDhiMehdjPvtxRmPy_Kuls2IdVsx",
    "expires" : ISODate("2020-06-10T03:09:30.396Z"),
    "session" : "{\"cookie\":{\"originalMaxAge\":28800000,\"expires\":\"2020-06-10T03:09:29.358Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"ebf7d73d-f3f2-4f96-8123-3f0f262ffff6\"}}"
}

However, when the express server is restarted passport clears the user out of the sessions storage when a user selects a route that requires auth (there by invoking the isAuth function). Meaning users are required to login in after server restart.

{
    "_id" : "GEEFIDhiMehdjPvtxRmPy_Kuls2IdVsx",
    "expires" : ISODate("2020-06-10T03:11:54.464Z"),
    "session" : "{\"cookie\":{\"originalMaxAge\":28800000,\"expires\":\"2020-06-10T03:11:54.464Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{}}"
}

My auth code is pretty standard stuff tbh, where am I going wrong here? I'm using the azure-ad passport strategy.

const passport = require('passport');
const OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const config = require('../config');

const store = new MongoStore({
  url: config.databaseUri,
});

// Usual passport code here findbyoid, ensureAuthenticated etc

function setupPassport(app) {
  app.use(
    session({
      secret: 'somepassword',
      resave: true,
      cookie: {
        maxAge: 8 * 60 * 60 * 1000,
      },
      saveUninitialized: true,
      store: store,
    })
  );
  app.use(passport.initialize());
  app.use(passport.session());
}
1 Answers

I wasn't actually storing the correct user information in the session or even looking in the session for the user information. Instead I was storing users in a local array and looking up their oid with deserializeUser function. the solution was to replace this with the code below.

passport.serializeUser(function (user, done) {
  done(null, user);
});

passport.deserializeUser(async (user, done) => {
  done(null, user);
});

This way the user object was stored in the session database and then recollected when a user checked auth.

Related