@goa/cookies

2.0.1 • Public • Published

@goa/cookies

npm version

@goa/cookies is a fork of 🗝 Signed And Unsigned Cookies Based On Keygrip Written In ES6, Annotated With Externs And Optimised With JavaScript Compiler.

yarn add @goa/cookies

Table Of Contents

API

The package is available by importing its default function:

import Cookies, { Keygrip, express, connect } from '@goa/cookies'

The deprecated secureProxy, maxage attributes of a cookie have been removed. The constructor only accepts the { keys: Array<string>|Keygrip } option, without being able to pass keys as an array, or Keygrip as an object. Please make sure no middleware is using these options.

class Cookies

Cookies is a Node.JS module for getting and setting HTTP(S) cookies. Cookies can be signed to prevent tampering, using Keygrip. It can be used with the built-in Node.JS HTTP library, or as Connect/Express middleware.

constructor(
  request: !http.IncomingMessage,
  response: !http.ServerResponse,
  options=: !CookiesOptions,
): Cookies

Creates a new cookies object to handle cookies.

This creates a cookie jar corresponding to the current request and response, additionally passing an object options.

A Keygrip object or an array of keys can optionally be passed as options.keys to enable cryptographic signing based on SHA1 HMAC, using rotated credentials.

A Boolean can optionally be passed as options.secure to explicitly specify if the connection is secure, rather than this module examining request.

Note that since this only saves parameters without any other processing, it is very lightweight. Cookies are only parsed on demand when they are accessed.

CookiesOptions: Options for the constructor.

Name Type Description
keys !(Array<string> | Keygrip) The array of keys, or the Keygrip object.
secure boolean Explicitly specifies if the connection is secure, rather than this module examining request.
Node.JS HTTP Server Example
import Cookies from '@goa/cookies'
import aqt from '@rqt/aqt'
import { createServer } from 'http'

// Optionally define keys to sign cookie values
// to prevent client tampering
const keys = ['keyboard cat']

const server = createServer((req, res) => {
  // Create a cookies object
  const cookies = new Cookies(req, res, { keys: keys })

  // Get a cookie
  const lastVisit = cookies.get('LastVisit', { signed: true })

  // Set the cookie to a value
  cookies.set('LastVisit', new Date().toISOString(), { signed: true })

  if (!lastVisit) {
    res.setHeader('Content-Type', 'text/plain')
    res.end('Welcome, first time visitor!')
  } else {
    res.setHeader('Content-Type', 'text/plain')
    res.end('Welcome back! Nothing much changed since your last visit at ' + lastVisit + '.')
  }
})

server.listen(async () => {
  const url = `http://localhost:${server.address().port}`
  console.log(url)
  let { body, headers } = await aqt(url)
  console.log(body, headers['set-cookie'].join('\n'))
  ;({ body } = await aqt(url, {
    headers: { Cookie: headers['set-cookie'] },
  }))
  console.log(body)
  server.close()
})
The output
http://localhost:55787
Welcome, first time visitor! LastVisit=2019-12-18T21:05:54.405Z; path=/; httponly
LastVisit.sig=RosnWirAT9-4bEgbxceOxUEQv-c; path=/; httponly
Welcome back! Nothing much changed since your last visit at 2019-12-18T21:05:54.405Z.

The overview of the Cookies interface is found in wiki.

set(
  name: string,
  value=: ?string,
  attributes=: !CookieSetOptions,
): void

This sets the given cookie in the response and returns the current context to allow chaining. If the value is omitted, an outbound header with an expired date is used to delete the cookie.

  • name* string: The name of the cookie to set.
  • value ?string (optional): The value to set.
  • attributes !CookieSetOptions (optional): The attributes and signed option.

CookieSetOptions extends CookieAttributes: How the cookie will be set.

Name Type Description Default
signed boolean Indicating whether the cookie is to be signed. If this is true, another cookie of the same name with the .sig suffix appended will also be sent, with a 27-byte url-safe base64 SHA1 value representing the hash of cookie-name=cookie-value against the first Keygrip key. This signature key is used to detect tampering the next time a cookie is received. false

The attributes accepted by the cookie instance are listed in wiki.

get(
  name: string,
  opts=: { signed: boolean },
): string|undefined

This extracts the cookie with the given name from the Cookie header in the request. If such a cookie exists, its value is returned. Otherwise, nothing is returned. { signed: true } can optionally be passed as the second parameter options. In this case, a signature cookie (a cookie of same name ending with the .sig suffix appended) is fetched. If no such cookie exists, nothing is returned. If the signature cookie does exist, the provided Keygrip object is used to check whether the hash of cookie-name=cookie-value matches that of any registered key:

  • If the signature cookie hash matches the first key, the original cookie value is returned.

  • If the signature cookie hash matches any other key, the original cookie value is returned AND an outbound header is set to update the signature cookie's value to the hash of the first key. This enables automatic freshening of signature cookies that have become stale due to key rotation.

  • If the signature cookie hash does not match any key, nothing is returned, and an outbound header with an expired date is used to delete the cookie.

  • name* string: The name of the cookie to get.

  • opts { signed: boolean } (optional): The options.

Wiki

Wiki contains the following pages with additional information about the package.

🍪 Cookie Attributes

Cookies Attributes: domain, expires, httpOnly, maxAge, overwrite, path, sameSite, secure

🚄 Express And Connect Middleware Constructor

Cookies can be used via express and connect easily by calling the middleware constructor functions to get middleware that can be installed on the app.

⚜️ Keygrip

The Keygrip can be passed in the keys property of the constructor. By default, the new instance of Keygrip will be created when an array of keys is passed, but custom implementations of Keygrip which override the sign and verify functions can be passed to cookies.

🔗 View Compiler Externs

The externs are required to compile the package yet keep the options' properties in tact, i.e. without renaming the properties. The API is preserved for 2nd level compilation in other packages, such as Goa, and is tested on the 1st level compilation of the package itself.

Copyright & License

GNU Affero General Public License v3.0

Original source, documentation and testing by Jed Schmidt and Douglas Christopher Wilson under MIT license found in COPYING file.

Forked Off cookies 0.7.3 Apr 24

Current: npm version

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

Readme

Keywords

Package Sidebar

Install

npm i @goa/cookies

Homepage

www.idio.cc/

Weekly Downloads

12

Version

2.0.1

License

AGPL-3.0

Unpacked Size

75.1 kB

Total Files

33

Last publish

Collaborators

  • zvr