Cookies Cookies

导读

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

与 Express 一起使用(默认)

首先安装 必需包(对于 TypeScript 用户,安装其类型):

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

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

ts
import * as cookieParser from 'cookie-parser'
// somewhere in your initialization file
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 的值将为false,而不是被篡改的值。

完成此操作后,您现在可以从路由处理程序中读取 Cookie,如下所示:

ts
@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
提示

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

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

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

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

提示

@Res() 装饰器从 @nestjs/common 导入,而 Responseexpress 包导入。

与 Fastify 一起使用

首先安装所需的包:

shell
$ npm i @fastify/cookie

安装完成后,注册 @fastify/cookie 插件:

ts
import fastifyCookie from '@fastify/cookie'

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter())
await app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
})

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

ts
@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
提示

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

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

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

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

警告

如果您想将响应处理逻辑留给框架,请记住将 passthrough 选项设置为 true,如上所示。阅读更多 此处

提示

@Res() 装饰器从 @nestjs/common 导入,而 FastifyReplyfastify 包导入。

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

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

ts
import { ExecutionContext, createParamDecorator } 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,并使用该值填充装饰参数。

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

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