NestJS Logo
NestJS 中文文档
v10.0.0
  • 介绍
  • 快速上手
  • 控制器
  • 提供者
  • 模块
  • 中间件
  • 异常过滤器
  • 管道
  • 守卫
  • 拦截器
  • 自定义装饰器
  • 自定义提供者
  • 异步提供者
  • 动态模块
  • 依赖注入作用域
  • 循环依赖
  • 模块引用
  • 懒加载模块
  • 执行上下文
  • 生命周期事件
  • 发现服务
  • 跨平台无关性
  • 测试
迁移指南
API 参考
官方课程
  1. 文档
  2. 功能扩展
  3. Cookie

日志
事件机制

Cookie

HTTP Cookie 是一种由浏览器存储的小型数据片段,通常用于在客户端与服务端之间维持会话状态。当用户再次访问网站时,浏览器会自动将 Cookie 随请求一起发送给服务器,从而实现状态记忆。

在 Express中使用

NestJS 默认使用 Express,因此可直接集成 cookie-parser 中间件来处理 Cookie。

首先,安装相关依赖:

npm install cookie-parser
npm install -D @types/cookie-parser

安装完成后,可在应用入口文件(通常是 main.ts)中将其注册为全局中间件:

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,防止暴露可能被篡改的原始内容。
  • 原始保留:无论签名验证结果如何,原始 Cookie 都会保留在 req.cookies 中。

在控制器中访问 Cookie

一旦中间件配置完成,即可在控制器方法中通过 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 到响应中

要在响应中写入 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。更多信息请参考响应处理方式。

在 Fastify 中使用

首先,安装所需的依赖包:

npm install @fastify/cookie

安装完成后,需要在应用初始化阶段注册 @fastify/cookie 插件:

main.ts
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 值
}