#Cache passport jwt strategy response

5 messages · Page 1 of 1 (latest)

slow nexus
#

I'm using passport-jwt strategy to validate my JWT against AWS Cognito. Is it possible to cache the JWT using a key that I should get back in response.body from AWS cognito and then check the cache first to get the payload before hitting cognito for subsequent requests?

elder slate
#

Yes, you can either store the key in memory (in a higher scoped variable) or you can use a keyvalule store/database.

severe ore
#

I'm using this in combination with Auth0. No passport though.
The idea is that jose can cache remote JWK set during startup, and then can perform fast, local JWT verification of any provided token.

Here's how to get JWK set from cognito. You should be able to adapt this: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html

import { Injectable } from '@nestjs/common';
import { ConfigService } from '../config';
import * as jose from 'jose';

@Injectable()
export class TokenService {
  private readonly JWKS;
  private readonly audience;

  constructor(
    private readonly configService: ConfigService,
  ) {
    this.JWKS = jose.createRemoteJWKSet(
      new URL(this.configService.get('AUTH_JWKS_URL')),
    );
    this.audience = this.configService.get('AUTH_AUDIENCE');
  }

  async verify(token: string) {
    try {
      const { payload } = await jose.jwtVerify(token, this.JWKS, {
        audience: this.audience,
      });
      return this.transformPayload(payload);
    } catch (error) {
      return false;
    }
  }

  private async transformPayload(payload: jose.JWTPayload) {
    const newPayload = {
      sub: payload.sub as string,
      email: payload[this.audience + '/email'] as string,
    };
    if (!newPayload.email) {
      throw new Error('Email not found in JWT payload');
    }
    if (!newPayload.sub) {
      throw new Error('Sub not found in JWT payload');
    }
    return newPayload;
  }
}
slow nexus