I have got an observation from SonarQube - Always sign JWTs and verify them using the verify() function before using the content of the token. Note that verify() returns decoded token value and there is no need to use the decode() function. So i had to change my code to below version.
import { HttpException, HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as jwks from 'jwks-rsa';
import * as jwt from 'jsonwebtoken';
@Injectable()
export class TokenValidation implements NestMiddleware {
constructor(private readonly configService: ConfigService) { }
async use(req: any, _res: any, next: () => void) {
const authHeader = req.headers.authorization;
const token = this.extractBearerToken(authHeader);
const client = jwks({
jwksUri: this.configService.get('JWKS_URL'),
});
try {
await new Promise<void>((resolve, reject) => {
jwt.verify(token, async (header, callback) => {
client.getSigningKey(header.kid, async (err, k) => {
if (err) {
reject(new HttpException('Token has expired', HttpStatus.UNAUTHORIZED));
} else {
const key = k.getPublicKey();
callback(null, key);
resolve();
}
});
}, { algorithms: ['RS256'] });
});
next();
} catch (error) {
if (error instanceof jwt.JsonWebTokenError) {
throw new HttpException('Token verification has failed', HttpStatus.UNAUTHORIZED);
} else {
throw new HttpException('Internal server error', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
}
While sending a bearer token, I am getting JsonWebTokenError: verify must be called asynchronous if secret or public key is provided as a callback. Where am I going wrong? Requesting the community's help.