NestJs + Passport - JWTStrategy 永远不会被 RS256 令牌调用

Posted

技术标签:

【中文标题】NestJs + Passport - JWTStrategy 永远不会被 RS256 令牌调用【英文标题】:NestJs + Passport - JWTStrategy never being called with RS256 tokens 【发布时间】:2019-08-01 04:01:08 【问题描述】:

我正在尝试在 nestjs 后端实现 RS256 JWT 令牌。我按照nestjs documentation 中提供的示例进行操作。

在我的模块中,我用我的私钥注册了JwtModule

@Module(
    imports: [
       PassportModule.register( defaultStrategy: 'jwt' ),
       JwtModule.register(
         secretOrPrivateKey: extractKey(`$process.cwd()/keys/jwt.private.key`),
         signOptions: 
            expiresIn: 3600,
         ,
       ),
    ],
    controllers: [AuthController],
    providers: [AuthService, JwtStrategy, HttpStrategy],
)
export class AuthModule 

我可以调用 auth/token 端点并获取令牌,但是当我尝试访问受保护的端点时,我总是得到 401。

您可以在下面找到我的自定义JwtStrategy

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) 
   constructor(private readonly authService: AuthService) 
      super(
          jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
          secretOrKey: extractKey(`$process.cwd()/keys/jwt.public.key`),
      );
   

   async validate(payload: JwtPayload) 
       console.log('JwtStrategy');
       const user = await this.authService.validateUser(payload);
       if (!user) 
           throw new UnauthorizedException();
       
       return user;
   

和受保护的端点:

@Controller('auth')
export class AuthController 
   constructor(private readonly authService: AuthService) 

   @Get('token')
   async createToken(): Promise<any> 
      return await this.authService.createToken();
   

   @Get('data')
   @UseGuards(AuthGuard())
   findAll() 
      console.log('Guarded endpoint');
      // This route is restricted by AuthGuard
      // JWT strategy
   

我假设当我调用 auth/data 时,我应该在控制台中至少看到我在 validate 方法中登录的“JwtStrategy”字符串。不幸的是,它从未出现过。为什么从不调用 validate 方法?

请在下面找到代码框

【问题讨论】:

【参考方案1】:

很可能公钥和/或私钥文件不是以 RS256 格式生成的。

我建议尝试以下方法:

https://gist.github.com/ygotthilf/baa58da5c3dd1f69fae9

【讨论】:

【参考方案2】:

不确定它是否有效,但你可以试试这个

@UseGuards(AuthGuard('jwt'))

在您的受保护路线上方。

【讨论】:

【参考方案3】:

您必须将 RS256 指定为 JwtModuleJwtStrategy 中的算法:

export class JwtStrategy extends PassportStrategy(Strategy) 
  constructor(private readonly authService: AuthService) 
    super(
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: publicKey,
      algorithms: ['RS256'],
      ^^^^^^^^^^^^^^^^^^^^^^
    );

JwtModule.register(
  secretOrPrivateKey: privateKey,
  signOptions: 
    expiresIn: 3600,
    algorithm: 'RS256',
    ^^^^^^^^^^^^^^^^^^^
  ,
),

【讨论】:

您的代码框中的示例也适用于我。但它实现了常规的 HS256 令牌。正如我在问题中所写,问题在于 RS256 令牌 - 所以使用 RSA 证书签名。 请看一下我的代码沙箱 - 我在我的问题中添加了一个链接。 对不起,我之前的回答不正确。查看我的编辑 除了在 JwtModule 和 JwtStrategy 中提供算法名称外,我只想补充一点,关键是还要有正确格式的键。私钥和公钥必须都是 RSA 格式。我的公钥是以 SSH2 格式提供的,这就是它不起作用的原因。

以上是关于NestJs + Passport - JWTStrategy 永远不会被 RS256 令牌调用的主要内容,如果未能解决你的问题,请参考以下文章

NestJs Passport jwt 未知策略

NestJS jwt-passport 身份验证

NestJS & Passport:更改用户密码时更改 JWT 令牌?

NestJs + Passport - JWTStrategy 永远不会被 RS256 令牌调用

Nest.js 中使用 @nestjs/passport 的可选身份验证

NestJS:使用 graphql 的 Passport LinkedIn 策略