jmazur
jmazur

Reputation: 135

NestJs + Passport - JWTStrategy never being called with RS256 tokens

I'm trying to implement RS256 JWT tokens in nestjs backend. I followed the example provided in nestjs documentation.

In my module I register the JwtModule with my private key:

@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 {}

I'm able to call auth/token endpoint and get the token but when I try to access guarded endpoint I always get 401.

Below you can find my custom 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;
   }
}

And guarded endpoint:

@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
   }
}

I assume that when I call the auth/data I should see in the console at least the "JwtStrategy" string that I log in the validate method. Unfortunately it never shows up. Why the validate method is never called?

Please find the codesandbox below

Edit Nest.js JWT Auth

Upvotes: 3

Views: 4453

Answers (3)

Adam W. Dennis
Adam W. Dennis

Reputation: 476

It's quite possible that the public key and/or private key files were not generated in RS256 format.

I'd recommend trying the following:

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

Upvotes: 0

Chetan Jain
Chetan Jain

Reputation: 241

Not sure if it works but you can try this

@UseGuards(AuthGuard('jwt'))

above your protected route.

Upvotes: 0

Kim Kern
Kim Kern

Reputation: 60507

You have to specify RS256 as the algorithm for in both the JwtModule and the JwtStrategy:

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

and

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

Upvotes: 7

Related Questions