I'm implementing an authentication with nestJS and passport.
I have one token, with expiration date of 14 days, and a refreshTime of 15 minutes (inside the payload). So if the user makes a request within 15 minutes, everything goes normal; but after that, it needs to be refreshed. I store signature of jwt inside another table and if it exists, I make a new token, if not I just throw not authenticated exception.
Here is the challenge: I need to set the newly created jwt token to response header.
Here is my code:
// jwt.strategy.ts
import { ConfigService } from '@nestjs/config';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { AuthService } from '../auth.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private configService: ConfigService,
private authService: AuthService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: configService.get('JWT_SECRET'),
passReqToCallback: true,
});
}
async validate(req: any, payload: any) {
const { refreshTime, sub, phoneNumber } = payload;
const tokenSignature = req.get('authorization').split('.').reverse()[0];
if (refreshTime < Date.now()) {
console.log('REFRESH');
this.authService.refreshToken(tokenSignature);
// **Set new token to response header**
}
return {
userId: sub,
phoneNumber,
tokenSignature,
};
}
}
I'm new to nestJs, and I actually don't know if this is the right place to do this or not.
Should I create an interceptor or something, or even handle this inside authGuard?
I could pass the response object from AuthGuard:
// jwt-auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext) {
const http = context.switchToHttp();
const res = http.getResponse();
const req = http.getRequest();
req.res = res;
return super.canActivate(context);
}
}