Sessions

@horsepower/session is a way to persist data from one request to another. There is many usages for using sessions, such as when your site has users that login/logout or maybe you want to remember a shopping cart. Sessions can be used here for making data persist from one page request to another.

Configuration

Sessions need to be configured through one and optionally two configurations. The main configuration is the config/session.js which describes how sessions need to work. The second optional config is the config/storage.js config when you store the sessions using a file store.

module.exports = {
  store: 'file',

  cookie: {
  path: '/',
    // Expire the cookie in approximately 30 days
    expires: new Date(Date.now() + (30 * 24 * 60 * 60 * 1000))
  }
}

Cookie options are required and are the options for creating the reference cookie on the client.

Since the store is set to file, the default session store will be used which points to the operating systems temp directory.

If you don't want sessions stored in the os's temp directory you can setup a custom location using a storage configuration. We need to label it as session with a driver type of file. Next we need to make sure that it points to the location of where the sessions will be stored.

module.exports = {
  disks: {
    session: {
      driver: 'file',
      root: storagePath('framework/sessions')
    }
  }
}

Usage

Sessions need to be started upon every request in order to use them. Thankfully there is middleware for that we can use that will do this for us (horsepower automatically closes open sessions after the response is sent if it has not already been ended).

In the following example we will assume that our website has a public facing side and a members facing side. On the members facing side we will work with sessions, and on the public side we will not.

const { Router } = require('@horsepower/router')
const { StartSession } = require('@horsepower/session')

// These pages do not require a session, so we will not start one
Router.get('/', 'welcome').name('welcome')
Router.post('/register', 'register')

// The pages in this group do require a session, so on every request to them
// we will automatically start the session.
Router.group('/member', { middleware: [StartSession] }, async () => {
  Router.get('/', 'user@home').name('home')
  Router.post('/login', 'user@login').name('login')
  Router.get('/settings', 'user@settings').name('settings')
})

Now with the above implemented, we can use sessions in our controller

module.exports.login = async function (client) {
  // Query the database for the user
  // We will assume the user was found for this example
  // const result = ....
  client.session.set('user', result)
  return client.response.redirect.to('home')
}

module.exports.home = async function (client) {
  return client.response.render('user-home.mix')
}