Nestjs passport-jwt ignore JWT signature

754 Views Asked by At

I can't pass any secret here, because it is stored in Redis for each user and I have to parse the token body before I can access the user id to get their secret. Using nestjs for architecture. Are there any elegant solutions without having to write whole copy of the strategy by myself?

export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: ???,
      passReqToCallback: true,
    });
  }

  async validate(req: any, payload: UserType): Promise<UserType> {
    try {
      const token = ExtractJwt.fromAuthHeaderAsBearerToken()(req);

      const [header, body] = token.split('.');

      const headerJSON = JSON.parse(btoa(header)) as { alg: Algorithm };
      const bodyJSON = JSON.parse(btoa(body)) as UserType;

      const sub = bodyJSON.sub;

      const userId = await this.authService.findUserSecret(sub);

      const jwt = new JwtService({
        secret: userId,
      });

      await jwt.verify(token, {
        algorithms: [headerJSON.alg],
      });

      return payload;
    } catch (e) {
      return Promise.reject();
    }
  }
}```
1

There are 1 best solutions below

0
On BEST ANSWER

Performed a bit more research and found this

      secretOrKeyProvider(request: any, rawJwtToken: string, done: any) {
        const [, body] = rawJwtToken.split('.');

        const bodyJSON = JSON.parse(btoa(body)) as UserType;

        const { sub } = bodyJSON;

        authService
          .findUserSecret(sub)
          .then(secret => secret || Promise.reject())
          .then(secret => done(null, secret))
          .catch(error => done(error, null));
      },