Skip to main content

Cookies

HTTP cookie是由用户浏览器存储的一小段数据。 Cookie被设计为网站记住有状态信息的可靠机制。 当用户再次访问网站时,Cookie会随请求自动发送。

在 Express 中使用(默认)

首先安装所需的包(对于 TypeScript 用户,还需要安装类型):

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

安装完成后,在全局中间件中应用 cookie-parser 中间件(例如,在您的 main.ts 文件中)。

import * as cookieParser from 'cookie-parser';

// 在初始化文件的某个地方
app.use(cookieParser());

您可以向 cookieParser 中间件传递多个选项:

  • secret:用于签名 cookie 的字符串或数组。这是可选的,如果未指定,将不解析已签名的 cookie。 如果提供了字符串,将用作密钥。如果提供了数组,将尝试使用每个密钥解开 cookie。
  • options:作为第二个选项传递给 cookie.parse 的对象。 有关详细信息,请参阅 cookie

该中间件将解析请求上的 Cookie 标头,并将 cookie 数据公开为 req.cookies 属性, 并且如果提供了密钥,则还公开为 req.signedCookies 属性。 这些属性是 cookie 名称到 cookie 值的键值对。

当提供了密钥时,此模块将验证并解开任何已签名的 cookie 值, 并将这些键值对从 req.cookies 移动到 req.signedCookies。 签名的 cookie 是一个值以 s: 为前缀的 cookie。 签名验证失败的签名 cookie 的值将为 false,而不是被篡改的值。

有了这个设置,现在您可以在路由处理程序内部读取 cookie,如下所示:

@Get()
findAll(@Req() request: Request) {
console.log(request.cookies); // 或 "request.cookies['cookieKey']"
// 或 console.log(request.signedCookies);
}
tip

@Req() 装饰器是从 @nestjs/common 导入的,而 Request 是从 express 包导入的。

要将 cookie 附加到输出响应,请使用 Response#cookie() 方法:

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
response.cookie('key', 'value')
}
warning

如果要将响应处理逻辑留给框架,请记住将 passthrough 选项设置为 true,如上所示。 阅读更多信息请参阅 这里

tip

@Res() 装饰器是从 @nestjs/common 导入的,而 Response 是从 express 包导入的。

在 Fastify 中使用

首先安装所需的包:

npm i @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,如下所示:

@Get()
findAll(@Req() request: FastifyRequest) {
console.log(request.cookies); // 或 "request.cookies['cookieKey']"
}
tip

@Req() 装饰器是从 @nestjs/common 导入的,而 FastifyRequest 是从 fastify 包导入的。

要将 cookie 附加到输出响应,请使用 FastifyReply#setCookie() 方法:

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
response.setCookie('key', 'value')
}

要了解更多关于 FastifyReply#setCookie() 方法的信息,请查阅 此页面

warning

如果要将响应处理逻辑留给框架,请记住将 passthrough 选项设置为 true,如上所示。 阅读更多信息请参阅 这里

tip

@Res() 装饰器是从 @nestjs/common 导入的,而 FastifyReply 是从 fastify 包导入的。

创建自定义装饰器(跨平台)

为了提供一种方便、声明性的方式来访问传入的 cookie,我们可以创建一个自定义装饰器

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const Cookies = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return data ? request.cookies?.[data] : request.cookies;
},
);

@Cookies() 装饰器将从 req.cookies 对象中提取所有 cookie, 或提取命名 cookie,并将带有该值的键值对填充到装饰的参数中。

有了这个设置,我们现在可以在路由处理程序签名中使用装饰器,如下所示:

@Get()
findAll(@Cookies('name') name: string) {}