@fastify/cookie

repository·main·Indexed 43 days ago

https://github.com/fastify/fastify-cookie

A plugin for Fastify version 11.1.2 that provides utilities for reading, setting, and clearing cookies. It includes support for signed cookies with key rotation, custom cookie signers, and automatic parsing into `req.cookies` via configurable Fastify hooks. Provides `reply.setCookie()`, `reply.clearCookie()`, and standalone `serialize` and `parse` functions.

Tokens
4K
Snippets
19
Records
22
Agent score
52%

What's inside fastify-cookie

  1. Implement key rotation for signed cookies

    main

    To rotate signing keys without invalidating existing cookies, provide an Array of keys to the secret option in the plugin configuration.

    Behavior:

    • The plugin always uses the first key in the array (keys[0]) to sign new cookies.
    • When parsing, the plugin iterates through the array to find a key that can successfully decode the signed cookie.
    • To complete a rotation, you must redeploy the server with a new secret array containing the new key at index 0 and the old key at index 1.

    Best Practice: Renewing cookies during rotation When a cookie is successfully unsigned but identified as being signed with an old key (result.renew === true), you should re-set the cookie so it is signed with the current primary key.

    // Registering with multiple keys for rotation
    fastify.register(require('@fastify/cookie'), {
      secret: [key1, key2]
    })
    
    // Renewing a cookie signed with an old key
    fastify.get('/', (req, reply) => {
      const result = reply.unsignCookie(req.cookies.myCookie)
    
      if (result.valid && result.renew) {
        reply.setCookie('myCookie', result.value, {
          domain: 'example.com',
          path: '/',
          signed: true
        })
      }
    })
  2. Security considerations for cookies

    main

    To protect your application, follow these security best practices when using @fastify/cookie:

    • Prevent XSS: Use options.httpOnly: true to prevent client-side scripts from accessing the cookie.
    • Prevent Tampering: Use options.signed: true to ensure cookies are not modified by the client.
    • Prevent Cookie Tossing: Use the __Host- cookie prefix for sensitive cookies.
    • Prevent MITM: Always use HTTPS for your application.
  3. Register @fastify/cookie in Fastify

    main

    Register the plugin with your Fastify instance. You can configure cookie signing with a secret, specify which Fastify hook to use for cookie parsing via hook, and provide parseOptions for cookie serialization.

    Important: Because cookie parsing happens via a Fastify hook, you should register this plugin before any other onRequest hooks that depend on cookie data.

    const fastify = require('fastify')()
    
    fastify.register(require('@fastify/cookie'), {
      secret: "my-secret", // for cookies signature
      hook: 'onRequest', // default: 'onRequest'. Options: 'onRequest', 'preParsing', 'preHandler', 'preValidation'.
      parseOptions: {}  // options for parsing cookies
    })
  4. Configure @fastify/cookie plugin options

    main

    The following options are available when registering the plugin:

    • secret (String | Array | Buffer | Object): Used to sign cookies. An Array allows for key rotation. An Object allows for custom signing mechanisms.
    • hook: The Fastify Hook to register cookie parsing into. Default is 'onRequest'. Valid values: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. Set to false to disable autoparsing.
    • algorithm: The hashing algorithm used to sign cookies. Default is 'sha256'.
    • parseOptions: An Object used to modify the serialization of set cookies (see parseOptions details below).
  5. Register the @fastify/cookie plugin

    main

    To use @fastify/cookie, register it as a plugin in your Fastify instance. You can provide a secret for signing cookies and a hook to determine when cookies are parsed from the request.

    Supported values for hook are: false, 'onRequest', 'preParsing', 'preValidation', or 'preHandler'. If set to false, cookies will not be automatically parsed into request.cookies.

    If a secret is provided, the plugin decorates the Fastify instance, Request, and Reply with signCookie and unsignCookie methods.

    const fastify = require('fastify')
    const fastifyCookie = require('@fastify/cookie')
    
    const server = fastify()
    
    server.register(fastifyCookie, {
      secret: 'my-secret-key',
      hook: 'onRequest' // default is 'onRequest'
    })
  6. Register @fastify/cookie with TypeScript

    main

    When using TypeScript, import FastifyCookieOptions to type your configuration object.

    import type { FastifyCookieOptions } from '@fastify/cookie'
    import cookie from '@fastify/cookie'
    import fastify from 'fastify'
    
    const app = fastify()
    
    app.register(cookie, {
      secret: "my-secret",
      parseOptions: {}
    } as FastifyCookieOptions)
  7. Use a custom cookie signer

    main

    Instead of a string or array of strings, the secret option can accept an object containing sign and unsign functions. This allows you to implement your own cryptographic logic for signing and verifying cookies.

    fastify.register(require('@fastify/cookie'), {
      secret: {
        sign: (value) => {
          // custom signing logic
          return signedValue
        },
        unsign: (value) => {
          return {
            valid: true,
            renew: false,
            value: 'unsignedValue'
          }
        }
      }
    })
  8. Manually unsign a cookie

    main

    If a secret was provided during plugin registration, the unsignCookie(value) method is available on the fastify instance, the request object, and the reply object. It returns an object containing valid (boolean), renew (boolean), and value (the original value).

    fastify.register(require('@fastify/cookie'), { secret: 'my-secret' })
    
    fastify.get('/', (req, rep) => {
      const { valid } = req.unsignCookie(req.cookies.foo)
      
      if (!valid) {
        return rep.send('cookie is invalid')
      }
    
      rep.send('cookie is valid')
    })
  9. Parse cookies from incoming requests

    main

    The plugin automatically parses cookies in the onRequest Fastify hook and attaches them to the request object as req.cookies. For example, a header Cookie: foo=bar results in req.cookies.foo being 'bar'.

    You can configure the underlying cookie parsing behavior by providing a parseOptions object in the plugin configuration.

    // Accessing parsed cookies in a handler
    fastify.get('/', (req, reply) => {
      const value = req.cookies.foo
    })
  10. Manually parse a cookie header

    main

    The parseCookie(cookieHeader) method is available on the fastify instance. It allows you to parse a raw Cookie header string into a JavaScript object without a request context.

    const cookies = fastify.parseCookie('sessionId=aYb4uTIhdBXC')
    // returns { sessionId: 'aYb4uTIhdBXC' }
  11. Clear cookies using clearCookie()

    main

    The clearCookie(name, options) method is available on the reply object to remove a cookie from the client.

    Parameters:

    • name: String name of the cookie to clear.
    • options: An optional object following the cookie serialize specification (e.g., to match the path or domain used when the cookie was set).
    fastify.get('/logout', (req, reply) => {
      reply.clearCookie('foo', { path: '/' })
    })