Skip to content
[fork] Simple session middleware for koa
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.documentary/section-breaks
.vscode
depack
documentary
example
src
test
types
.alamoderc.json
.eslintignore
.eslintrc
.gitignore
CHANGELOG.md
LICENSE
README.md
package.json
yarn.lock

README.md

@goa/session

npm version

@goa/session is a fork of Simple session middleware for Koa written in ES6 and optimised with JavaScript Compiler. It is used in the Idio web server.

yarn add @goa/session

Table Of Contents

API

The package is available by importing its default function:

import session from '@goa/session'

session(
  app: _goa.App,
  options?: _idio.KoaSessionConfig,
): _goa.Middleware

The interface is changed from the original package, so that the app is always passed as the first argument.

_idio.KoaSessionConfig: Configuration passed to koa-session.

Name Type Description Default
key string Cookie key. koa:sess
maxAge (string | number) maxAge in ms with default of 1 day. Either a number or 'session'. session will result in a cookie that expires when session/browser is closed. Warning: If a session cookie is stolen, this cookie will never expire. 86400000
overwrite boolean Can overwrite or not. true
httpOnly boolean httpOnly or not. true
signed boolean Signed or not. true
autoCommit boolean Automatically commit headers. true
valid function(!_goa.Context, *): boolean The validation hook: valid session value before use it. -
beforeSave function(!_goa.Context, !_idio.KoaSession): boolean The hook before save session. -
genid function(!_goa.Context): string The way of generating external session id. uuid-v4
store _idio.ContextStore You can store the session content in external stores (Redis, MongoDB or other DBs) by passing options.store with three methods (these need to be async functions). -
externalKey { get: function(_goa.Context), set: function(_goa.Context, string) } External key is used the cookie by default, but you can use options.externalKey to customize your own external key methods. -
ContextStore function(new: _idio.ContextStore, !_goa.Context) If your session store requires data or utilities from context, opts.ContextStore is also supported. -
prefix string If you want to add prefix for all external session id. It will not work if options.genid(ctx) present. -
encode function(!Object): string Use options.encode and options.decode to customize your own encode/decode methods. -
decode function(string): !Object Use options.encode and options.decode to customize your own encode/decode methods. -
rolling boolean Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. false
renew boolean Renew session when session is nearly expired, so we can always keep user logged in. false
import aqt from '@rqt/aqt'
import Goa from '@goa/koa'
import session from '@goa/session'

const app = new Goa()
app.keys = ['g', 'o', 'a']
app.use(session(app, { signed: false })) // normally, signed should be true
app.use((ctx) => {
  if (ctx.path == '/set') {
    ctx.session.message = 'hello'
    ctx.body = 'You have cookies now:'
  } else if (ctx.path == '/exit') {
    ctx.session = null
    ctx.body = 'Bye'
  }
  else ctx.body = `Welcome back: ${ctx.session.message}`
})
app.listen(async function() {
  const { port } = this.address()
  const url = `http://localhost:${port}`

  // 1. Acquire cookies
  let { body, headers } = await aqt(`${url}/set`)
  console.log(body, headers, '\n')
  const cookies = headers['set-cookie']

  // 2. Exploit cookies
  ;({ body, headers } = await aqt(url, {
    headers: {
      'Cookie': cookies.join(';'),
    },
  }))
  console.log(body, headers, '\n')

  // 3. Destroy cookies
  ;({ body, headers } = await aqt(`${url}/exit`, {
    headers: {
      'Cookie': cookies.join(';'),
    },
  }))
  console.log(body, headers)

  this.close()
})
You have cookies now: { 'content-type': 'text/plain; charset=utf-8',
  'content-length': '21',
  'set-cookie': 
   [ 'koa:sess=eyJtZXNzYWdlIjoiaGVsbG8iLCJfZXhwaXJlIjoxNTYxODYwMDUyMzc5LCJfbWF4QWdlIjo4NjQwMDAwMH0=; path=/; expires=Sun, 30 Jun 2019 02:00:52 GMT; httponly' ],
  date: 'Sat, 29 Jun 2019 02:00:52 GMT',
  connection: 'close' } 

Welcome back: hello { 'content-type': 'text/plain; charset=utf-8',
  'content-length': '19',
  date: 'Sat, 29 Jun 2019 02:00:52 GMT',
  connection: 'close' } 

Bye { 'content-type': 'text/plain; charset=utf-8',
  'content-length': '3',
  'set-cookie': 
   [ 'koa:sess=; path=/; expires=Sun, 30 Jun 2019 02:00:52 GMT; httponly' ],
  date: 'Sat, 29 Jun 2019 02:00:52 GMT',
  connection: 'close' }

If your session store requires data or utilities from context, opts.ContextStore is also supported. ContextStore must be a class which claims three instance methods demonstrated above. new ContextStore(ctx) will be executed on every request.

_idio.ContextStore

Name Type Description
get* (key, maxAge, { rolling: boolean }) => Promise<*> Get session object by key.
set* (key, sess, maxAge, { rolling, changed }) => Promise Set session object for key, with a maxAge (in ms, or as 'session').
destroy* * Destroy session for key.
Show an example context store.
const sessions = {}

export default class ContextStore {
  constructor(ctx) {
    this.ctx = ctx
  }

  async get(key) {
    return sessions[key]
  }

  async set(key, value) {
    sessions[key] = value
  }

  async destroy(key) {
    sessions[key] = undefined
  }
}

The session object itself (ctx.session) has the following methods.

_idio.KoaSession

Name Type Description
isNew* boolean Returns true if the session is new.
populated* boolean Populated flag, which is just a boolean alias of .length.
maxAge* (number | string) Get/set cookie's maxAge.
_maxAge* number Private JSON serialisation.
_expire* number Private JSON serialisation.
_session* string Private JSON serialisation.
_sessCtx* _idio.KoaContextSession Private JSON serialisation.
_ctx* _goa.Context Private JSON serialisation.
save* function(): void Save this session no matter whether it is populated.
manuallyCommit* function(): Promise Session headers are auto committed by default. Use this if autoCommit is set to false.

Copyright

Original Work by dead-horse and contributors.


Art Deco © Art Deco for Idio 2019 Idio Tech Nation Visa Tech Nation Visa Sucks

You can’t perform that action at this time.