HTTP Cookie 是一种由浏览器存储的小型数据片段,通常用于在客户端与服务端之间维持会话状态。当用户再次访问网站时,浏览器会自动将 Cookie 随请求一起发送给服务器,从而实现状态记忆。
NestJS 默认使用 Express,因此可直接集成 cookie-parser 中间件来处理 Cookie。
首先,安装相关依赖:
npm install cookie-parser
npm install -D @types/cookie-parser安装完成后,可在应用入口文件(通常是 main.ts)中将其注册为全局中间件:
import * as cookieParser from 'cookie-parser'
app.use(cookieParser())cookie-parser() 中间件接收两个可选参数:
secret:用于签名 Cookie 的密钥,可以是字符串或字符串数组。如果不传该参数,则不会解析已签名的 Cookie;如果传入数组,中间件会依次尝试使用每个密钥进行解签。options:传递给底层 cookie.parse() 方法的配置选项。详细配置请参考 cookie 模块文档。该中间件会自动解析 HTTP 请求头中的 Cookie 字段,并将解析结果挂载到 req.cookies 对象上。如果设置了密钥参数,已签名的 Cookie 还会被解析到 req.signedCookies 对象中。
已签名的 Cookie 是指值以 s: 前缀开头的 Cookie。中间件会自动验证这些 Cookie 的签名完整性:
req.signedCookies 中。false,防止暴露可能被篡改的原始内容。req.cookies 中。一旦中间件配置完成,即可在控制器方法中通过 Request 对象读取 Cookie,例如:
import { Req } from '@nestjs/common'
import type { Request } from 'express'
@Get()
findAll(@Req() request: Request) {
console.log(request.cookies['cookieKey'])
// 或 console.log(request.signedCookies)
}要在响应中写入 Cookie,可以使用 Express 的 Response.cookie() 方法。如下所示:
import { Res } from '@nestjs/common'
import { Response } from 'express'
@Get()
findAll(@Res({ passthrough: true }) response: Response) {
response.cookie('key', 'value')
}如果希望保留由 Nest 自动处理响应的能力,请务必将 @Res() 装饰器的
passthrough 选项设置为
true。更多信息请参考响应处理方式。
首先,安装所需的依赖包:
npm install @fastify/cookie安装完成后,需要在应用初始化阶段注册 @fastify/cookie 插件:
import fastifyCookie from '@fastify/cookie'
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
)
await app.register(fastifyCookie, {
secret: 'my-secret', // 用于对 Cookie 进行签名
})配置完成后,即可在控制器中访问客户端发送的 Cookie。例如:
import { Req } from '@nestjs/common'
import { FastifyRequest } from 'fastify'
@Get()
findAll(@Req() request: FastifyRequest) {
console.log(request.cookies) // 或 request.cookies['cookieKey']
}如果你需要向客户端设置 Cookie,可以通过 FastifyReply#setCookie() 方法实现:
import { Res } from '@nestjs/common'
import { FastifyReply } from 'fastify'
@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
response.setCookie('key', 'value')
}如需了解 setCookie() 方法的更多选项和用法,建议查阅官方文档。
如果希望框架继续接管响应处理流程,必须将 @Res() 装饰器的 passthrough
选项设为
true,如上述示例所示。更多说明请参考控制器章节。
为了更方便地在控制器中访问请求携带的 Cookie 信息,我们可以定义一个自定义装饰器,实现声明式地提取 Cookie 值。
import { createParamDecorator, ExecutionContext } from '@nestjs/common'
// 自定义装饰器:用于获取请求中的 Cookie
export const Cookies = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest()
// 若指定了 Cookie 名称,则返回对应的值;否则返回所有 Cookie
return data ? request.cookies?.[data] : request.cookies
}
)@Cookies() 装饰器的核心逻辑是从 req.cookies 中提取信息。
如果你不传入参数,它会返回所有的 Cookie;如果传入某个 Cookie 名称,则返回对应的值。最终结果会被注入到装饰的参数上。
有了这个装饰器后,你就可以在控制器方法中像下面这样使用:
@Get()
findAll(@Cookies('name') name: string) {
// 这里的 name 参数将自动接收到名为 'name' 的 Cookie 值
}