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();
}
}
}```
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));
},