1

I have a scenario where I dont want to get 401 unauthorized response when token is expired. So I planned implement it using interceptor, to check token expiry and if token expired I will redirect to login page and want to cancel the API call. I get the token expiry status and it redirects to login page but still the API call is happening and receiving 401 response. If I cancel the API request from interceptor, I feel I wont have the problem. How to cancel the API call?

Is there a better way to do this, if whatevr I am thinking is not correct way?

1 Answers1

2

It may be the answer if your token is follow JWT standard jwt.io . If you check the link you'll know that the token has sperate into 3 parts and the payload part is just encoded not encrypted, so you can check the payload for token expiration on the client side.

*.interceptor.ts

export class AuthInterceptorService implements HttpInterceptor {
  constructor(private authService: AuthService) {}
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = this.authService.getAuthToken();

    if (token) {
      const payload = parseJwt(token); // decode JWT payload part.
      if (Date.now() >= payload.exp * 1000) { // Check token exp.
        // redirect user to login page or auto refresh user's token and then replace the expired one and continue the process.
        return NEVER;
      }

      // If we have a token, we set it to the header
      request = request.clone({
        setHeaders: {Authorization: `Authorization token ${token}`}
      });
    }

    return next.handle(request).pipe(
      catchError((err) => {
        if (err instanceof HttpErrorResponse) {
          if (err.status === 401) {
            // redirect user to the logout page
          }
        }
        return throwError(err);
      })
    );
  }
}

export function parseJwt(token): any {
  const base64Url = token.split('.')[1];
  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
  const jsonPayload = decodeURIComponent(window.atob(base64).split('').map((c) => {
    return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  }).join(''));

  return JSON.parse(jsonPayload);
}
paranaaan
  • 1,626
  • 2
  • 9
  • 17