Cookies

Cookies

在 HTTP 请求期间,请求 cookie 会自动被解析。你可以使用 request 对象读取 cookie,并使用 response 对象设置/清除 cookie。

读取 cookie
import router from '@adonisjs/core/services/router'
router.get('cart', async ({ request }) => {
const cartItems = request.cookie('cart_items', [])
console.log(cartItems)
})
设置 cookie
import router from '@adonisjs/core/services/router'
router.post('cart', async ({ request, response }) => {
const id = request.input('product_id')
response.cookie('cart_items', [{ id }])
})
清除 cookie
import router from '@adonisjs/core/services/router'
router.delete('cart', async ({ request, response }) => {
response.clearCookie('cart_items')
})

配置

设置 cookie 的默认配置在 config/app.ts 文件中定义。你可以根据应用程序的需求调整这些选项。

http: {
cookie: {
domain: '',
path: '/',
maxAge: '2h',
httpOnly: true,
secure: true,
sameSite: 'lax',
/**
* 实验性属性
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#partitioned
*/
partitioned: false,
priority: 'medium',
}
}

这些选项会被转换为 set-cookie 属性maxAge 属性接受基于字符串的时间表达式,并且其值会被转换为秒。

在设置 cookie 时,可以覆盖同一组选项。

response.cookie('key', value, {
domain: '',
path: '/',
maxAge: '2h',
httpOnly: true,
secure: true,
sameSite: 'lax',
})

支持的数据类型

cookie 值使用 JSON.stringify 序列化为字符串;因此,你可以将以下 JavaScript 数据类型用作 cookie 值。

  • string
  • number
  • bigInt
  • boolean
  • null
  • object
  • array
// Object
response.cookie('user', {
id: 1,
fullName: 'virk',
})
// Array
response.cookie('product_ids', [1, 2, 3, 4])
// Boolean
response.cookie('is_logged_in', true)
// Number
response.cookie('visits', 10)
// BigInt
response.cookie('visits', BigInt(10))
// Date 对象会被转换为 ISO 字符串
response.cookie('visits', new Date())

使用 response.cookie 方法设置的 cookie 是签名的。签名 cookie 防篡改,意味着更改其内容将使签名无效,并且 cookie 将被忽略。

cookie 使用 config/app.ts 文件中定义的 appKey 进行签名。

签名 cookie 仍然可以通过 Base64 解码来读取。如果你希望 cookie 值不可读,可以使用加密 cookie。

import router from '@adonisjs/core/services/router'
router.get('/', async ({ request, response }) => {
// 设置签名 cookie
response.cookie('user_id', 1)
// 读取签名 cookie
request.cookie('user_id')
})

与签名 cookie 不同,加密 cookie 的值无法解码为明文。因此,你可以使用加密 cookie 来存储包含敏感信息的值,这些值不应被任何人读取。

加密 cookie 使用 response.encryptedCookie 方法设置,并使用 request.encryptedCookie 方法读取。在底层,这些方法使用 Encryption 模块

import router from '@adonisjs/core/services/router'
router.get('/', async ({ request, response }) => {
// 设置加密 cookie
response.encryptedCookie('user_id', 1)
// 读取加密 cookie
request.encryptedCookie('user_id')
})

当你希望前端代码使用 document.cookie 值访问 cookie 时,可以使用普通 cookie。

默认情况下,我们会对原始值调用 JSON.stringify 并将其转换为 base64 编码字符串。这样做是为了使你能够使用 objectsarrays 作为 cookie 值。然而,可以关闭编码。

普通 cookie 使用 response.plainCookie 方法定义,并使用 request.plainCookie 方法读取。

import router from '@adonisjs/core/services/router'
router.get('/', async ({ request, response }) => {
// 设置普通 cookie
response.plainCookie('user', { id: 1 }, {
httpOnly: true
})
// 读取普通 cookie
request.plainCookie('user')
})

要关闭编码,请在选项对象中设置 encode: false

response.plainCookie('token', tokenValue, {
httpOnly: true,
encode: false,
})
// 读取关闭编码的普通 cookie
request.plainCookie('token', {
encoded: false
})

以下指南涵盖了编写测试时使用 cookie 的方法。