jonathan
jonathan

Reputation: 43

Express Session - Configure Session Timeout and Lifetime

I'm currently migrating an Express single sign on application to a new identity provider. This new IdP requires the following session standards.

  1. Session timeout: 1 hour
  2. Session lifetime: 3 hours

If I'm interpreting this correctly the session should terminate after 1 consecutive hour of idle time or 3 hours after the session was initially generated, whichever occurs first. The relevant npm packages being used are express-session 1.15.6 and connect-mongo 2.0.1. At this point I've been able to achieve both these session parameters, but not simultaneously. I can either...

  1. Implement 1 hour session timeout by setting session cookie maxAge to 1 hour and session rolling to true, thus resetting the cookie expires field with every response. As stated in connect-mongo if a cookie has an expiry it's applied to the session ttl field. So renewing the cookie effectively renews the session indefinitely as long as the timeout doesn't occur.
  2. Implement 3 hour session lifetime by setting session cookie maxAge to 3 hours and session rolling to false. Now the session ttl isn't reset with every response and 3 hours after the session was created it will be terminated.

As stated above, I can't get both of these working at the same time. Any insight would be helpful as I have very little web dev experience. I've researched changing the index TTL which gave me some initial hope. I believed I could add another date field to the session object which wasn't dependent on the session cookie expires value, a createdAt date. I could then use the cookie expires as the timeout component and the createdAt date for the lifetime component. Unfortunately I'm having no luck adding this value to the session object. Am I overlooking an obvious express session option or connect-mongo setting which would solve my problem?

    app.use(session({
    secret: keys.expressSession.pw,
    saveUninitialized: false, // don't create a session for anonymous users
    resave: false, // save the session to store even if it hasn't changed
    rolling: true, // reset expiration on every response
    name: "definitely not a connect cookie",
    cookie: {   
        httpOnly: true, 
        maxAge: 60*1000, // one minute timeout
        //maxAge: 180*1000 // three minute lifetime
        secure: false // https only, when true add proxy trust
    },
    store: new MongoStore({
        url:keys.mongodb.dbURI,     
        // ttl: value of cookie maxAge, set redundantly in case cookie has no expiry
    })
}));

Upvotes: 1

Views: 1942

Answers (1)

docnoe
docnoe

Reputation: 71

I don't have time to test anything, but maybe this helps to point you in the right direction.

It is possible to change the cookie.maxAge per request, so you could calculate the maxAge every time.

From express-session docs

Alternatively req.session.cookie.maxAge will return the time remaining in milliseconds, which we may also re-assign a new value to adjust the .expires property appropriately.

So a middleware could look something like this

app.use(function (req, res, next) {
  const hour = 3600
  const threeHours = hour * 3
  const creationDate = req.session.createdAt // set this when the session is initialized
  const expires = creationDate + threeHours // expiration date
  const ttl = expires - Date.now() // maximum time to life

  if (ttl < hour) {
    // if the maximum time to live is less than the one hour timeout, use it as maxAge
    req.session.cookie.maxAge = ttl
  } else {
    // otherwise just stick with the "idle" timeout of 1 hour
    req.session.cookie.maxAge = hour
  }
  next()
})

Upvotes: 1

Related Questions