cookie-session icon indicating copy to clipboard operation
cookie-session copied to clipboard

Enable multiple cookie-sessions

Open ZacTredger opened this issue 3 years ago • 0 comments

Enables the user to create arbitrarily many cookie-sessions, whose options can differ. The API design was motivated by ensuring backwards compatibility with v2 (more details in the Discussion below).

Fixes:

  • #149
  • #170 (because why not?)

The new features are pretty comprehensively tested, and I'm using them in production. But I'm still happy to discuss alternative APIs/implementations. I've also got a sister fork of Definitely Typed with updated typings. I'll create a PR there when this gets merged.

I'm requesting to merge into master because I noticed that you have some WIP changes on develop.

Example

A fairly complex example taken from the new tests to illustrate the new features:

app = connect()
app.use(session([
  {
    signed: false,
  }, {
    signed: false,
    name: 'secondary',
    sessionName: 'secondary',
  }
]))
app.use(function (req, _res, next) {
  req.session.name = req.sessionOptions.name
  req.sessions.secondary.name = req.sessionsOptions.secondary.name
  next()
})
app.use('/', function (req, res, _next) {
  res.end(req.session.name + req.sessions.secondary.name)
})

request(app)
  .get('/')
  .expect(shouldHaveCookie('session'))
  .expect(shouldHaveCookie('secondary'))
  .expect(200, 'sessionsecondary', done)
})

Discussion

I tend to discuss the "why", including rejected alternative designs, in my commit messages. But I've basically reproduced that commentary here for convenience.

Enable setting multiple cookie-sessions

Introduces a new option, 'sessionName', which is the key under Express.Request.sessions where the session can be accessed. 'session' is the default sessionName, and sessions with sessionName 'session' are still accessible at Express.Request.session. This API was chosen to avoid breaking existing applications.

Rejected alternative APIs:

  • The name property acts as the session accessor on req.sessions. Either obviating the need for the sessionName option, or perhaps allowing the sessionName to default to name. This would be a breaking change in all apps that provide a non-default value for name. I considered working around this by always making the first cookie-session created the one accessible at req.session, but this felt hacky and potentially confusing.
  • Each session is accessed by adding its sessionName as a property on req. I feared this would pollute the namespace, risking name collisions with other modules.

Call cookieSession with multiple options objects

Users can now pass several, or an array of, options objects to cookieSession. One middleware function will always be returned that creates all the sessions. This means that users using multiple cookie-sessions in their app never need to call cookieSession multiple times. cookieSession now also checks that the sessions have unique names and sessionNames to avoid tricky overwriting bugs.

I rejected an alternative approach, in which cookieSession returns an array of middleware functions. You can pass Express an array of middleware exactly like passing a single functions, so it wouldn't break any user's apps in those cases. But we can't assume that all users are passing the function straight to Express.

ZacTredger avatar Jan 19 '23 15:01 ZacTredger