【问题标题】:NestJs + Passport - JWTStrategy never being called with RS256 tokensNestJs + Passport - JWTStrategy 永远不会被 RS256 令牌调用
【发布时间】: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 方法?

请在下面找到代码框

【问题讨论】:

    标签: javascript jwt passport.js nestjs passport-jwt


    【解决方案1】:

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

    我建议尝试以下方法:

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

    【讨论】:

      【解决方案2】:

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

      @UseGuards(AuthGuard('jwt'))
      

      在您的受保护路线上方。

      【讨论】:

        【解决方案3】:

        您必须将 RS256 指定为 JwtModule 和 JwtStrategy 中的算法:

        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 格式提供的,这就是它不起作用的原因。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 2013-10-12
        • 2012-03-27
        • 2013-08-29
        • 2013-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多