Cookie Helper
The Cookie Helper provides an easy interface to manage cookies, enabling developers to set, parse, and delete cookies seamlessly.
Import
import { Hono } from 'hono'
import {
deleteCookie,
getCookie,
getSignedCookie,
setCookie,
setSignedCookie,
generateCookie,
generateSignedCookie,
} from 'hono/cookie'Usage
Regular cookies
app.get('/cookie', (c) => {
setCookie(c, 'cookie_name', 'cookie_value')
const yummyCookie = getCookie(c, 'cookie_name')
deleteCookie(c, 'cookie_name')
const allCookies = getCookie(c)
// ...
})Signed cookies
NOTE: Setting and retrieving signed cookies returns a Promise due to the async nature of the WebCrypto API, which is used to create HMAC SHA-256 signatures.
app.get('/signed-cookie', (c) => {
const secret = 'secret' // make sure it's a large enough string to be secure
await setSignedCookie(c, 'cookie_name0', 'cookie_value', secret)
const fortuneCookie = await getSignedCookie(
c,
secret,
'cookie_name0'
)
deleteCookie(c, 'cookie_name0')
// `getSignedCookie` will return `false` for a specified cookie if its signature fails verification
const allSignedCookies = await getSignedCookie(c, secret)
// ...
})NOTE
getSignedCookie distinguishes two cases. A cookie that has a signature but fails verification returns false. A cookie that does not have a valid signature format is treated as not being a signed cookie at all and returns undefined — the same as when the cookie is not present. This rule applies both when retrieving a single cookie by name and when retrieving all signed cookies. Since both false and undefined are falsy, if (!value) handles both cases.
Cookie Generation
generateCookie and generateSignedCookie functions allow you to create cookie strings directly without setting them in the response headers.
generateCookie
// Basic cookie generation
const cookie = generateCookie('delicious_cookie', 'macha')
// Returns: 'delicious_cookie=macha; Path=/'
// Cookie with options
const cookie = generateCookie('delicious_cookie', 'macha', {
path: '/',
secure: true,
httpOnly: true,
domain: 'example.com',
})generateSignedCookie
// Basic signed cookie generation
const signedCookie = await generateSignedCookie(
'delicious_cookie',
'macha',
'secret chocolate chips'
)
// Signed cookie with options
const signedCookie = await generateSignedCookie(
'delicious_cookie',
'macha',
'secret chocolate chips',
{
path: '/',
secure: true,
httpOnly: true,
}
)Note: Unlike setCookie and setSignedCookie, these functions only generate the cookie strings. You need to manually set them in headers if needed.
Options
setCookie & setSignedCookie
- domain:
string - expires:
Date - httpOnly:
boolean - maxAge:
number - path:
string - secure:
boolean - sameSite:
'Strict'|'Lax'|'None' - priority:
'Low' | 'Medium' | 'High' - prefix:
secure|'host' - partitioned:
boolean
Example:
// Regular cookies
setCookie(c, 'great_cookie', 'banana', {
path: '/',
secure: true,
domain: 'example.com',
httpOnly: true,
maxAge: 1000,
expires: new Date(Date.UTC(2000, 11, 24, 10, 30, 59, 900)),
sameSite: 'Strict',
})
// Signed cookies
await setSignedCookie(
c,
'fortune_cookie',
'lots-of-money',
'secret ingredient',
{
path: '/',
secure: true,
domain: 'example.com',
httpOnly: true,
maxAge: 1000,
expires: new Date(Date.UTC(2000, 11, 24, 10, 30, 59, 900)),
sameSite: 'Strict',
}
)deleteCookie
- path:
string - secure:
boolean - domain:
string
Example:
deleteCookie(c, 'banana', {
path: '/',
secure: true,
domain: 'example.com',
})deleteCookie returns the deleted value:
const deletedCookie = deleteCookie(c, 'delicious_cookie')__Secure- and __Host- prefix
The Cookie helper supports __Secure- and __Host- prefixes for cookie names.
If you want to verify if the cookie name has a prefix, specify the prefix option.
const securePrefixCookie = getCookie(c, 'yummy_cookie', 'secure')
const hostPrefixCookie = getCookie(c, 'yummy_cookie', 'host')
const securePrefixSignedCookie = await getSignedCookie(
c,
secret,
'fortune_cookie',
'secure'
)
const hostPrefixSignedCookie = await getSignedCookie(
c,
secret,
'fortune_cookie',
'host'
)Also, if you wish to specify a prefix when setting the cookie, specify a value for the prefix option.
setCookie(c, 'delicious_cookie', 'macha', {
prefix: 'secure', // or `host`
})
await setSignedCookie(
c,
'delicious_cookie',
'macha',
'secret choco chips',
{
prefix: 'secure', // or `host`
}
)Following the best practices
A New Cookie RFC (a.k.a cookie-bis) and CHIPS include some best practices for Cookie settings that developers should follow.
- RFC6265bis-13
Max-Age/Expireslimitation__Host-/__Secure-prefix limitation
- CHIPS-01
Partitionedlimitation
Hono is following the best practices. The cookie helper will throw an Error when parsing cookies under the following conditions:
- The cookie name starts with
__Secure-, butsecureoption is not set. - The cookie name starts with
__Host-, butsecureoption is not set. - The cookie name starts with
__Host-, butpathis not/. - The cookie name starts with
__Host-, butdomainis set. - The
maxAgeoption value is greater than 400 days. - The
expiresoption value is 400 days later than the current time.