nestjspassport.jspassport-jwtnestjs-passport

Access response in passport strategy


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?


Solution

  • 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);
      }
    }