0

I'm trying to write a service that will take a JWT token and verify it using a public key that's in the JWKS JSON format. I believe I can grab the key and convert it into a KeyObject (no idea if this is necessary), but I can't quite figure out how to convert it into whatever format verifyAsync needs, which I'm guessing is PEM format. Here's the code I have so far:

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { KeyObject, createPublicKey } from 'crypto';

@Injectable()
export class TokenValidationService {
  constructor(
    private jwtService: JwtService
  ) { }

  async validate(token: string): Promise<any | boolean> {
    const jwt = this.jwtService.decode(token);
    if (!jwt) {
      return false;
    }

    const jwks: Response = await fetch('https://xxxxxx.auth0.com/.well-known/jwks.json');
    const jwksJson = await jwks.json();
    
    const key: KeyObject = createPublicKey({
      key: jwksJson.keys[0],
      format: 'jwk'
    })

    // TODO: Somehow convert this KeyObject into a string that verifyAsync accepts

    await this.jwtService.verifyAsync(token, {
      algorithms: ['RS256'],
      publicKey: myKeyString
    })

    return jwt;
  }
}

Any help would be appreciated.

Mike Christensen
  • 88,082
  • 50
  • 208
  • 326

1 Answers1

0

Ok, I think I figured it out. I'd still be interested if there's a better way to go about doing this.

    const key: KeyObject = createPublicKey({
      key: jwksJson.keys[0],
      format: 'jwk'
    })

    const exportedKey: string = key.export({ type: 'pkcs1', format: 'pem' }).toString();

    const verifiedJwt = await this.jwtService.verifyAsync(token, {
      algorithms: ['RS256'],
      publicKey: exportedKey,
      ignoreExpiration: true
    })
Mike Christensen
  • 88,082
  • 50
  • 208
  • 326