#Refresh access token in AuthGuard from passport

3 messages · Page 1 of 1 (latest)

austere jasper
#

Hey there,

I'm currently working on a scenario where I need to verify if the access token has expired and refresh it using the refresh token, all within the canActivate method of the AuthGuard. However, I've encountered an issue: if the access token expires and I make a call, it throws a 401 Unauthorized response from passport validation. Oddly, after this response, the cookies get set.

I'm wondering if there's a more efficient approach to managing the access token based on cookies. Any suggestions or insights would be greatly appreciated!

Thanks in advance!

   const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
     context.getHandler(),
     context.getClass()
   ]);

   if (isPublic) {
     return true;
   }

   const req = context.switchToHttp().getRequest();
   const res = context.switchToHttp().getResponse();

   try {
     const { accessToken, refreshToken } = req.signedCookies;

     if (accessToken) {
       return this.activate(context);
     }

     const payload: JwtToken = this.tokenService.isTokenValid(refreshToken);
     const existingToken = await this.tokenService.findOneByToken(payload);

     if (!existingToken || !existingToken?.isValid) {
       throw new HttpException('Authentication invalid', HttpStatus.UNAUTHORIZED);
     }

     this.tokenService.attachCookiesToResponse(res, payload.user, existingToken.refreshToken);
     return this.activate(context);
   } catch (err) {
     throw new HttpException('Authentication invalid', HttpStatus.UNAUTHORIZED);
   }
 }```
#

This is the function for setting the cookies

    const accessTokenJWT = this.jwtService.sign({ user });
    const refreshTokenJWT = this.jwtService.sign({ user, refreshToken });

    console.log('CREATE TOKENS: ', accessTokenJWT, refreshTokenJWT);
    const oneHour = 1000 * 10;
    //const oneHour = 1000 * 60 * 60;
    const oneDay = 1000 * 60 * 60 * 24;

    res.cookie('accessToken', accessTokenJWT, {
      httpOnly: true,
      secure: this.configService.get('NODE_ENV') === 'production',
      signed: true,
      expires: new Date(Date.now() + oneHour)
    });

    res.cookie('refreshToken', refreshTokenJWT, {
      httpOnly: true,
      secure: this.configService.get('NODE_ENV') === 'production',
      signed: true,
      expires: new Date(Date.now() + oneDay)
    });
  }```
rose patio
#

all within the canActivate method of the AuthGuard
This won't work. Your jwt auth guard should only be checking the validity of the access token. No setting. No refreshing. Access tokens should also be sent via Authorization header as a bearer token from the client. Not sent via cookie.

Your refresh process should be behind a normal REST endpoint. And in the endpoint, the validity of the refresh token (put into an HTTP Only cookie with the path set to your refresh endpoint) is checked. If it is valid, then a new refresh and access token is sent back. The access token in the response, the refresh token back into the cookie.