RiserBob logoRiserBobv1.0.0
HomeDocsCLIRelease notes

Getting started

  • Introduction
  • Installation
  • Quick start
  • Project structure

Core concepts

  • Routing
  • Request
  • Responses
  • Error handling

Middleware

  • Middleware
  • Authentication
  • Logger and CORS

Data

  • Validation

Structure and tooling

  • Modules
  • CLI

Examples

  • Build a project
  • Mongoose
  • Drizzle ORM
  • Sequelize
  • JWT and cookies
  • File uploads

Packages

  • Cookies

Resources

  • Troubleshooting
  • Release notes
  • License
  • Security
  • Contributing
Packages

Cookies

@riser-bob/cookie: secure cookie management with signing, rotation and safe defaults.

@riser-bob/cookie reads request cookies, sets and deletes cookies, signs values with HMAC-SHA256 and applies Set-Cookie headers to a response. It is a separate package, and it works with or without the framework. AuthMiddleware uses it to read the token in 'cookie' and 'both' modes.

Terminal
bun add @riser-bob/cookie

Use it in a route

TypeScript
import { CookieManager } from '@riser-bob/cookie' bob.spongGet('/cookie/set', (spongReq, spongRes) => {  const cookies = CookieManager.fromRequest(spongReq.request)   cookies.set('theme', 'dark', { maxAge: 3600 })   return cookies.applyTo(spongRes.SpongOK({ message: 'Cookie created' }))})

Call applyTo() on the final response. Without it, the cookies you set are never sent.

Secure by default

Every cookie starts from these defaults, and any option you pass overrides them.

TypeScript
{ path: '/', httpOnly: true, secure: true, sameSite: 'lax' }
Browsers can refuse Secure cookies over plain HTTP, and Safari rejects them on http://localhost. For local development, pass defaults: { secure: false } when you create the manager.
TypeScript
const cookies = CookieManager.fromRequest(spongReq.request, {  defaults: { secure: process.env.NODE_ENV === 'production' },})

CookieManager

TypeScript
new CookieManager(cookieHeader?, options?)
MemberDescription
CookieManager.fromRequest(request, options?)Creates a manager from a Fetch Request.
get(name)Returns the value, or undefined.
has(name)Checks presence only. It does not validate a session.
names()Names of the cookies in the current view.
getAll()A snapshot object of all names and values.
set(name, value, options?)Queues a Set-Cookie header. Returns the manager.
setSigned(name, value, options?)Same, but signs the value. Needs a secret.
getSigned(name)Returns the original value, or undefined if missing, unsigned or tampered.
delete(name, options?)Queues an expired cookie so the browser removes it.
getSetCookieHeaders()A copy of the pending Set-Cookie headers.
applyTo(response)Appends one Set-Cookie header per pending cookie.
headerRejectedtrue when the incoming Cookie header was ignored for being too large.

Manager options

OptionDescription
secretsSecrets used by setSigned and getSigned. The first one signs, every one verifies.
defaultsCookie options applied to every cookie, replacing the built-in defaults you override.
maxHeaderBytesLargest incoming Cookie header that will be parsed. Default 16 KiB.

Signed cookies

TypeScript
const cookies = CookieManager.fromRequest(spongReq.request, {  secrets: [process.env.COOKIE_SECRET!],}) cookies.setSigned('session', sessionId, { maxAge: 60 * 60 * 24 * 7 }) const value = cookies.getSigned('session')
  • Each secret must be a string of at least 32 characters.
  • The first secret signs new cookies. Every secret is tried when verifying, which makes rotation painless.
  • The cookie name is part of what is signed, so a valid cookie cannot be copied under another name.
Signing does not encrypt. The value stays readable by the client. A valid signature also does not prove the session is still active, so check it against your own store.

Deleting a cookie

TypeScript
cookies.delete('session', { path: '/', sameSite: 'lax' })

The browser only removes a cookie when path, domain and the other attributes match the original, so pass the same ones you used to set it. As with set, the deletion only reaches the browser through applyTo.

Options

OptionDescription
domainDomain that can receive the cookie.
pathURL path for which the cookie is available.
expiresAbsolute expiration date.
maxAgeLifetime in seconds.
httpOnlyHides the cookie from document.cookie.
secureRestricts sending to secure contexts.
sameSite'lax', 'strict' or 'none'. 'none' requires secure.
priority'low', 'medium' or 'high'.
partitionedPartitioned storage. Requires secure.

Limits

  • maxAge and a future expires are capped at 400 days.
  • A serialized cookie larger than 4096 bytes is rejected.
  • An incoming Cookie header larger than 16 KiB is ignored. Change it with maxHeaderBytes.
  • __Secure- and __Host- prefixes are validated for you.

CookieError

Mistakes such as a bad name or a missing secret throw a CookieError with a code. Reading cookies never throws.

CodeMeaning
INVALID_NAMEInvalid cookie name.
INVALID_VALUEThe value must be a string.
INVALID_OPTIONInvalid or incompatible cookie option.
COOKIE_TOO_LARGEThe serialized cookie exceeds the size limit.
SERIALIZATION_FAILEDSerialization failed.
SECRETS_REQUIREDA secret is needed to sign a cookie.
WEAK_SECRETA secret is too short or invalid.
PreviousFile uploadsNextTroubleshooting

On this page

  • Use it in a route
  • Secure by default
  • CookieManager
  • Manager options
  • Signed cookies
  • Deleting a cookie
  • Options
  • Limits
  • CookieError