I have a working nestjs passport JWT strategy, it returns a 401 unauthorized with invalid or missing bearer token, however, it does not set the response header WWW-Authenticate header, which I need to do for a client library that is expecting that in the header
In my AuthModule I register as so:
JwtModule.register({
secret: jwtConstants.secret,
signOptions: { expiresIn: '1m' }
})
I've also estended the JWT-strategy as follows:
import { ExtractJwt, Strategy } from 'passport-jwt';
import { jwtConstants } from './constants';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
validate(payload: {
sub: string;
email: string;
}): { userId: string; email: string } {
return {
userId: payload.sub,
email: payload.email
};
}
}
How can I set WWW-Authenticate header, only in the case the strategy fails / returns 401?
I managed to solve it with a slightly different approach, you can use Exception Filters to intercept auth failures, this worked for me, perhaps someone will find it of use:
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
constructor() {}
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
if (status === 401) {
response.setHeader(
'WWW-Authenticate',
'Basic realm="Access to site", charset="UTF-8"',
);
}
response.status(status).json(exception.getResponse());
}
}
Then I can implement it globally in my main.ts as follows:
app.useGlobalFilters(new HttpExceptionFilter());