跳到主要内容

会话

HTTP 会话提供了一种在多个请求之间存储关于用户信息的方法, 这对于 MVC 应用程序特别有用。

在 Express(默认)中使用

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

npm i express-session
npm i -D @types/express-session

安装完成后,在全局中间件中应用 express-session(例如,在你的 main.ts 文件中):

import * as session from 'express-session';
// 在初始化文件的某处
app.use(
session({
secret: 'my-secret',
resave: false,
saveUninitialized: false,
}),
);
备注

默认的服务器端会话存储故意不设计用于生产环境。 在大多数情况下,它会泄漏内存,不能扩展到多个进程,并且只用于调试和开发。 在官方存储库中了解更多信息。

secret 用于对会话 ID cookie 进行签名。这可以是一个字符串表示单个密钥,也可以是多个密钥的数组。 如果提供了密钥数组,则仅使用第一个元素对会话 ID cookie 进行签名,而在验证请求中的签名时,将考虑所有元素。 密钥本身不应该容易被人解析,并且最好是一组随机字符。

启用 resave 选项会强制将会话保存回会话存储,即使在请求期间未修改会话。 默认值为 true,但已弃用使用默认值,因为将来默认值将更改。

同样,启用 saveUninitialized 选项会强制将“未初始化”的会话保存到存储中。 会话在新建但未修改时是未初始化的。 选择 false 对于实现登录会话、减少服务器存储使用或符合要求在设置 cookie 前获得许可的法律很有用。 选择 false 还将有助于处理客户端在没有会话的情况下进行多个并行请求的竞争条件。

您可以向session中间件传递其他选项,可以在 API 文档中了解更多信息。

备注

请注意,secure: true 是一个推荐的选项。 但是,它要求网站启用了 https,即,对于安全的 cookie,需要使用 HTTPS。如果设置了 secure, 并且通过 HTTP 访问站点,将不会设置 cookie。 如果将 node.js 放在代理后面并使用 secure: true,则需要在 Express 中设置 "trust proxy"

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

@Get()
findAll(@Req() request: Request) {
request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
提示

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

或者,您可以使用 @Session() 装饰器从请求中提取会话对象,如下所示:

@Get()
findAll(@Session() session: Record<string, any>) {
session.visits = session.visits ? session.visits + 1 : 1;
}
提示

@Session() 装饰器从 @nestjs/common 包中导入。

在 Fastify 中使用

首先安装所需的包:

$ npm i @fastify/secure-session

安装完成后,注册 fastify-secure-session 插件:

import secureSession from '@fastify/secure-session';

// 在初始化文件的某处
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
);
await app.register(secureSession, {
secret: 'averylogphrasebiggerthanthirtytwochars',
salt: 'mq9hDxBVDbspDR6n',
});
备注

您还可以预生成密钥(请参阅说明)或使用密钥轮换。

官方存储库中阅读有关可用选项的更多信息。

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

@Get()
findAll(@Req() request: FastifyRequest) {
const visits = request.session.get('visits');
request.session.set('visits', visits ? visits + 1 : 1);
}

或者,您可以使用 @Session() 装饰器从请求中提取会话对象,如下所示:

@Get()
findAll(@Session() session: secureSession.Session) {
const visits = session.get('visits');
session.set('visits', visits ? visits + 1 : 1);
}
提示

@Session() 装饰器从 @nestjs/common 导入, secureSession.Session@fastify/secure-session 包中导入 (导入语句:import * as secureSession from '@fastify/secure-session')。