Cookie
Elysia 提供了一个可变的 signal 用于与 Cookie 交互。
没有 get/set,你可以直接提取 cookie 名称并检索或更新其值。
import { Elysia } from 'elysia'
new Elysia()
.get('/', ({ cookie: { name } }) => {
// Get
name.value
// Set
name.value = "New Value"
})
默认情况下,Reactive Cookie 可以自动编码/解码对象类型,这允许我们将 cookies 视为对象,而无需担心编码/解码。它就是能用。
Reactivity
Elysia 的 cookie 是响应式的。这意味着当你更改 cookie 值时,cookie 将基于类似于 signals 的方法自动更新。
Elysia cookie 提供了一个单一真相来源来处理 cookies,它具有自动设置标头和同步 cookie 值的能力。
由于 cookies 默认是依赖 Proxy 的对象,提取的值永远不会是 undefined;相反,它将始终是 Cookie<unknown>
的值,可以通过调用 .value 属性获取。
我们可以将 cookie jar 视为常规对象,对其迭代只会迭代已存在的 cookie 值。
Cookie 属性
要使用 Cookie 属性,你可以使用以下任一方法:
- 直接设置属性
- 使用
set
或add
更新 cookie 属性。
有关更多信息,请参阅 cookie 属性配置。
分配属性
你可以像操作任何普通对象一样获取/设置 cookie 的属性,响应式模型会自动同步 cookie 值。
import { Elysia } from 'elysia'
new Elysia()
.get('/', ({ cookie: { name } }) => {
// get
name.domain
// set
name.domain = 'millennium.sh'
name.httpOnly = true
})
set
set 允许通过 重置所有属性 和用新值覆盖属性,一次更新多个 cookie 属性。
import { Elysia } from 'elysia'
new Elysia()
.get('/', ({ cookie: { name } }) => {
name.set({
domain: 'millennium.sh',
httpOnly: true
})
})
add
与 set 类似,add 允许我们一次更新多个 cookie 属性,但它只会覆盖定义的属性,而不是重置。
remove
要移除 cookie,你可以使用以下任一方法:
- name.remove
- delete cookie.name
import { Elysia } from 'elysia'
new Elysia()
.get('/', ({ cookie, cookie: { name } }) => {
name.remove()
delete cookie.name
})
Cookie Schema
你可以使用 t.Cookie
的 cookie schema 严格验证 cookie 类型并提供 cookie 的类型推断。
import { Elysia, t } from 'elysia'
new Elysia()
.get('/', ({ cookie: { name } }) => {
// Set
name.value = {
id: 617,
name: 'Summoning 101'
}
}, {
cookie: t.Cookie({
name: t.Object({
id: t.Numeric(),
name: t.String()
})
})
})
可空 Cookie
要处理可空的 cookie 值,你可以在想要设置为可空的 cookie 名称上使用 t.Optional
。
import { Elysia, t } from 'elysia'
new Elysia()
.get('/', ({ cookie: { name } }) => {
// Set
name.value = {
id: 617,
name: 'Summoning 101'
}
}, {
cookie: t.Cookie({
name: t.Optional(
t.Object({
id: t.Numeric(),
name: t.String()
})
)
})
})
Cookie 签名
通过引入 Cookie Schema 和 t.Cookie
类型,我们可以创建一个统一的类型,用于自动处理 sign/verify cookie 签名。
Cookie 签名是附加到 cookie 值的加密哈希,使用密钥和 cookie 内容生成,通过向 cookie 添加签名来增强安全性。
这确保 cookie 值未被恶意行为者修改,有助于验证 cookie 数据的真实性和完整性。
使用 Cookie 签名
通过提供 cookie 密钥和 sign
属性来指示哪些 cookie 应进行签名验证。
import { Elysia, t } from 'elysia'
new Elysia()
.get('/', ({ cookie: { profile } }) => {
profile.value = {
id: 617,
name: 'Summoning 101'
}
}, {
cookie: t.Cookie({
profile: t.Object({
id: t.Numeric(),
name: t.String()
})
}, {
secrets: 'Fischl von Luftschloss Narfidort',
sign: ['profile']
})
})
Elysia 然后会自动对 cookie 值进行签名和取消签名。
构造函数
你可以使用 Elysia 构造函数设置全局 cookie secret
和 sign
值,而不是在每个需要的路由中内联,从而将其应用到所有全局路由。
import { Elysia, t } from 'elysia'
new Elysia({
cookie: {
secrets: 'Fischl von Luftschloss Narfidort',
sign: ['profile']
}
})
.get('/', ({ cookie: { profile } }) => {
profile.value = {
id: 617,
name: 'Summoning 101'
}
}, {
cookie: t.Cookie({
profile: t.Object({
id: t.Numeric(),
name: t.String()
})
})
})
Cookie 轮换
Elysia 会自动处理 Cookie 的密钥轮换。
Cookie 轮换是一种迁移技术,使用较新的密钥对 cookie 进行签名,同时也能够验证 cookie 的旧签名。
import { Elysia } from 'elysia'
new Elysia({
cookie: {
secrets: ['Vengeance will be mine', 'Fischl von Luftschloss Narfidort']
}
})
配置
以下是 Elysia 接受的 cookie 配置。
secret
用于签名/取消签名 cookies 的密钥。
如果传递数组,将使用 Key Rotation。
Key rotation 是当加密密钥被退休并替换为生成的新加密密钥时。
以下是扩展自 cookie 的配置。
domain
指定 Domain Set-Cookie 属性 的值。
默认情况下,不设置域,大多数客户端会认为 cookie 仅适用于当前域。
encode
@default encodeURIComponent
指定一个函数,用于编码 cookie 的值。
由于 cookie 的值具有有限的字符集(并且必须是简单的字符串),此函数可用于将值编码为适合 cookie 值的字符串。
默认函数是全局 encodeURIComponent
,它会将 JavaScript 字符串编码为 UTF-8 字节序列,然后 URL-编码超出 cookie 范围的任何序列。
expires
指定 Date 对象作为 Expires Set-Cookie 属性 的值。
默认情况下,不设置过期时间,大多数客户端会认为这是一个“非持久 cookie”,并在满足像退出 Web 浏览器应用这样的条件时删除它。
TIP
cookie 存储模型规范 规定,如果同时设置了 expires
和 maxAge
,则 maxAge
优先,但并非所有客户端都会遵守此规定,因此如果同时设置,它们应该指向相同的日期和时间。
httpOnly
@default false
指定 HttpOnly Set-Cookie 属性 的布尔值。
当为 truthy 时,设置 HttpOnly 属性,否则不设置。
默认情况下,不设置 HttpOnly 属性。
TIP
设置此值为 true 时要小心,因为合规客户端将不允许客户端 JavaScript 在 document.cookie
中看到 cookie。
maxAge
@default undefined
指定数字(以秒为单位)作为 Max-Age Set-Cookie 属性 的值。
给定的数字将通过向下取整转换为整数。默认情况下,不设置最大年龄。
TIP
cookie 存储模型规范 规定,如果同时设置了 expires
和 maxAge
,则 maxAge
优先,但并非所有客户端都会遵守此规定,因此如果同时设置,它们应该指向相同的日期和时间。
path
指定 Path Set-Cookie 属性 的值。
默认情况下,路径处理程序被视为默认路径。
priority
指定字符串作为 Priority Set-Cookie 属性 的值。 low
将 Priority 属性设置为 Low。 medium
将 Priority 属性设置为 Medium,这是未设置时的默认优先级。 high
将 Priority 属性设置为 High。
有关不同优先级级别的信息,可参阅 规范。
TIP
这是一个尚未完全标准化的属性,未来可能会发生变化。这也意味着许多客户端在理解它之前可能会忽略此属性。
sameSite
指定布尔值或字符串作为 SameSite Set-Cookie 属性 的值。 true
将 SameSite 属性设置为 Strict 以进行严格的同站强制执行。 false
不会设置 SameSite 属性。 'lax'
将 SameSite 属性设置为 Lax 以进行宽松的同站强制执行。 'none'
将 SameSite 属性设置为 None 以明确跨站 cookie。 'strict'
将 SameSite 属性设置为 Strict 以进行严格的同站强制执行。 有关不同强制执行级别的信息,可参阅 规范。
TIP
这是一个尚未完全标准化的属性,未来可能会发生变化。这也意味着许多客户端在理解它之前可能会忽略此属性。
secure
指定 Secure Set-Cookie 属性 的布尔值。当为 truthy 时,设置 Secure 属性,否则不设置。默认情况下,不设置 Secure 属性。
TIP
设置此值为 true 时要小心,因为合规客户端如果浏览器没有 HTTPS 连接,将不会在未来将 cookie 发送回服务器。