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

提取JWT时Request未定义问题排查:NestJS+Passport框架下HttpOnly Cookie存储JWT的认证异常

解决NestJS中JWT Cookie提取器req未定义的问题

看起来你遇到的问题大概率和GraphQL上下文的请求传递有关(从你的AuthResolver能看出来这是个GraphQL项目),而非@nestjs/passport本身的bug。下面分步骤帮你排查和解决:

1. 先确保Cookie解析中间件已配置

不管是REST还是GraphQL项目,NestJS都不会自动解析Cookie,所以第一步要安装并启用cookie-parser:

首先安装依赖:

npm install cookie-parser

然后在main.ts中添加中间件:

import * as cookieParser from 'cookie-parser';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(cookieParser()); // 启用Cookie解析
  await app.listen(3000);
}
bootstrap();

2. 自定义JwtAuthGuard适配GraphQL上下文

默认的AuthGuard('jwt')是为REST API设计的,在GraphQL中,请求对象不是直接传递给Passport策略的,需要我们手动从GraphQL的执行上下文中提取request:

修改你的auth.guard.ts:

import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  // 重写getRequest方法,从GraphQL上下文获取req
  getRequest(context: ExecutionContext) {
    const gqlContext = GqlExecutionContext.create(context);
    return gqlContext.getContext().req;
  }
}

这样修改后,Passport就能正确拿到request对象,你的自定义Token提取器里的req就不会是undefined了。

3. 验证Request类型导入

确保你在jwt.strategy.ts中导入的是Express的Request类型,避免类型不匹配导致的问题:

import { Request } from 'express'; // 正确导入
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([
        (req: Request) => req?.cookies?.access_token,
      ]),
      ignoreExpiration: false,
      secretOrKey: 'qweqweqweqeqwe',
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}

为什么会出现req未定义?

在GraphQL请求中,NestJS的执行上下文和REST不同,默认的AuthGuard不会自动把GraphQL上下文里的req传递给Passport策略,导致你的自定义提取器拿不到request对象。通过重写getRequest方法,我们手动把GraphQL上下文里的req传递给Passport,就能解决这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 06:37:38