You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

cookie-session设置req.session=null后浏览器Cookie未清除的问题

问题描述

根据cookie-session官方文档,销毁会话可通过req.session = null实现。在NestJS应用中,我通过@Session()装饰器获取会话并为其赋值userId属性:

@Post('/signin')
@Serialize(UserDto)
async signin(@Body() body: SigninUserDto, @Session() session: any) {
  const user = await this.authService.signin(body);
  session.userId = user.id;
  return user;
} 

此操作会在浏览器中创建会话Cookie:
会话Cookie截图

但执行登出操作时,我按照文档将session设为null,浏览器中的会话Cookie却仍可见:

@Post('/signout')
@UseGuards(AuthGuard)
@Serialize(UserDto)
signout(@Session() session: any) {
  session = null;
}

补充说明:前端使用NextJS实现基础登录表单,登录后跳转至带登出按钮的首页,点击按钮会调用NestJS的登出接口执行session=null操作。

请问:

  • 浏览器中会话Cookie仍可见的原因是什么?
  • 是否存在安全隐患?
  • 如何彻底清除会话?

问题分析与解决方案

原因:局部变量赋值未修改真实会话对象

你在登出方法里直接给session局部变量赋值null,这只是改变了变量本身的引用,并没有触碰到req.session这个真实的会话对象。NestJS的@Session()装饰器注入的是req.session的引用,但直接给局部变量赋值不会影响原对象,所以cookie-session没有触发销毁会话的逻辑,浏览器里的Cookie自然不会被清除。

安全隐患:存在身份验证失效风险

虽然浏览器里还能看到Cookie,但如果会话数据没被正确销毁,用户执行登出后,后续请求可能仍携带有效会话,导致登录状态无法正常清除。另外,残留的Cookie可能被攻击者尝试利用,虽然多数情况下无效,但仍存在潜在的伪造请求风险。

彻底清除会话的正确方法

必须直接修改req.session为null,而不是局部变量。可以通过@Request()装饰器获取完整的请求对象来操作:

import { Request } from 'express';

@Post('/signout')
@UseGuards(AuthGuard)
@Serialize(UserDto)
signout(@Request() req: Request) {
  req.session = null;
}

这样操作后,cookie-session会自动在响应头中添加Set-Cookie指令,将会话Cookie的过期时间设为过去的时间,浏览器收到后就会自动清除该Cookie。

如果需要更手动的方式,也可以直接清除Cookie:

import { Response } from 'express';

@Post('/signout')
@UseGuards(AuthGuard)
signout(@Response() res: Response) {
  res.clearCookie('session'); // 替换成你的会话Cookie实际名称
  res.status(200).send({ message: '登出成功' });
}

注意使用@Response()时需要手动发送响应,否则请求会一直挂起。


内容的提问来源于stack exchange,提问作者JustinD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:43:25