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

NestJS后端无法向浏览器设置Cookie(Postman测试正常)

NestJS设置Cookie浏览器不生效问题排查与解决

问题现象

在NestJS服务中通过拦截器设置Cookie,Postman测试时Cookie正常生效,但浏览器无法获取到Cookie。

相关代码

Cookie设置拦截器

type Res = {
  token?: string
  refresh_token?: string
}

@Injectable()
export class CookieAttacherInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const response = context.switchToHttp().getResponse<Response>()

    return next
      .handle()
      .pipe(
        map((res: Res) => {
          if (res && (res.token || res.refresh_token)) {
            const auth = {
              token: res.token,
              refresh_token: res.refresh_token
            }
            response.cookie('auth-cookie', auth, {
              httpOnly: true,
              expires: new Date(Date.now() + 100 * 24 * 60 * 60 * 1000),
              sameSite: 'none',
              domain: process.env.COOKIE_DOMAIN || '',
              secure: true,
            })
          }
          const { token, refresh_token, ...result } = res
          return result
        })
      )
  }
}

登录控制器

@Post('/login')
@UseInterceptors(CookieAttacherInterceptor)
async loginWithPassword(
  @Body() loginDto: LoginDto,
  @Res({ passthrough: true }) response: Response
) {
  const { statusCode, data } = await this.authService.loginWithPassword(loginDto)
  response.status(statusCode)
  return data
}

CORS配置

app.enableCors({
  credentials: true,
  origin: '*',
  methods: ['GET', 'PUT', 'POST', 'DELETE']
})

相关截图

响应头中已返回Set-Cookie字段
浏览器Cookie面板中无对应的auth-cookie

解决方案

以下是几个关键修复点:

  1. 修正CORS的origin配置
    当credentials: true时,origin不能设为*,必须指定具体的前端域名(比如http://localhost:3000),否则浏览器会拒绝保存Cookie。修改后的CORS配置示例:

    app.enableCors({
      credentials: true,
      origin: process.env.FRONTEND_DOMAIN || 'http://localhost:3000', // 替换为你的前端域名
      methods: ['GET', 'PUT', 'POST', 'DELETE']
    })
    
  2. 调整SameSite与Secure的配合

    • 当设置sameSite: 'none'时,必须同时开启secure: true,但这仅适用于HTTPS环境。如果是本地HTTP开发环境,需要将sameSite改为'lax'或'strict',并关闭secure:
      response.cookie('auth-cookie', auth, {
        httpOnly: true,
        expires: new Date(Date.now() + 100 * 24 * 60 * 60 * 1000),
        sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
        domain: process.env.COOKIE_DOMAIN || 'localhost',
        secure: process.env.NODE_ENV === 'production',
      })
      
  3. 确保Domain配置正确
    domain字段不要留空,本地开发时设为'localhost',生产环境设置为对应域名(比如'.yourdomain.com'支持子域名)。

  4. 前端请求需携带credentials
    前端发起请求时,必须设置withCredentials: true:

    • Axios示例:
      axios.post('/login', loginData, { withCredentials: true })
      
    • Fetch示例:
      fetch('/login', {
        method: 'POST',
        credentials: 'include',
        body: JSON.stringify(loginData)
      })
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:43:24