提取 JWT 时请求未定义

Posted

技术标签:

【中文标题】提取 JWT 时请求未定义【英文标题】:request undefined when extracting JWT 【发布时间】:2021-05-13 05:49:26 【问题描述】:

我已关注此guide,试图让 JWT 身份验证正常工作。

我唯一的区别是我将 JWT 令牌保留在 HttpOnly cookie 中,这意味着需要自定义提取器。

我找到了一个example ,介绍了如何从 cookie 中提取令牌。所以,唯一的区别是:

jwtFromRequest: ExtractJwt.fromExtractors([(req: Request) => 
  return req?.cookies?.access_token
])

很遗憾,requndefined 没有明显的原因。

这就是我的 auth.module.ts 的样子:

@Module(
  imports: [
    PassportModule,
    JwtModule.register(
      secret: 'qweqweqweqeqwe',
      signOptions:  expiresIn: '20s' 
    )
  ],
  providers: [
    AuthService,
    AuthResolver,
    JwtAuthGuard,
    JwtStrategy
  ]
)
export class AuthModule  

我还创建了一个策略文件jwt.stragegy.ts

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

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

auth.guard.ts

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') 

这可能是 passport.js 库方面的错误吗? 就像,@nestjs/passport 无法映射参数或其他东西......

【问题讨论】:

你确定req 是什么undefined?您是否安装了 cookie-parser 中间件? @JayMcDoniel 绝对是。此外,当打印arguments 时——长度为 0。关于 cookie-parser——它已被激活,在其他地方我什至可以访问我的 cookie。 app.use(cookieParser()) 就是这样。 【参考方案1】:

按照文档,您应该能够收到请求。

import  ExecutionContext  from '@nestjs/common';
import  GqlExecutionContext  from '@nestjs/graphql';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') 
  getRequest(context: ExecutionContext) 
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  

【讨论】:

【参考方案2】:

在我的场景中,导致 payload.sub 未定义的是 auth.service 上的 login 函数。

之前(不工作)

async login(user: any) 
    const payload =  apiKey: user.apiKey, sub: user.userId ;
    const token = this.jwtService.sign(payload);

    return `Access token=$token;\n HttpOnly;\n Path=/;\n Max- 
    Age=$this.configService.get('jwtConstants.expirationTime')`;

更改后(工作)

async login(user: any) 
    const payload =  apiKey: user._doc.apiKey, sub: user._doc._id ;
    const token = this.jwtService.sign(payload);

    return `Access token=$token;\n HttpOnly;\n Path=/;\n Max-Ag
    e=$this.configService.get('jwtConstants.expirationTime')`;

【讨论】:

以上是关于提取 JWT 时请求未定义的主要内容,如果未能解决你的问题,请参考以下文章

在获取用户时使用 Passport-jwt 时 req.user 未定义

@@ nestjs / jwt-无法读取未定义的属性'挑战'

在注册时,在数据库中创建了用户,但在浏览器中检查时 JWT 令牌是“未定义的”

无法读取未定义的 reactjs JWT 身份验证的属性“令牌”

Laravel 的尝试()方法未定义(JWT)

Passport JWT req.user 在我的一条路线中未定义