Search code examples
javascriptangularangular-http-interceptors

Cannot rety request after receive 403 in interceptor


I am tring to intercept the request that result in 403 (because the token expire) and then perform a request to get a new token to be able to perfom again the request that fails.

But for some reason the next.handle(request) with the new token didn't perform the request that was intercept.

@Injectable()
export class AuthExpiredInterceptor implements HttpInterceptor {
  constructor(
    private accountService: AccountService,
    private readonly authService: AuthService,
    private readonly router: Router
  ) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error) => {
        if (error instanceof HttpErrorResponse && error.status === 403) {
          this._handle403Error(request, next);
        }
        return throwError(error);
      })
    );
  }

  _handle403Error(request: HttpRequest<any>, next: HttpHandler) {
    const refreshToken = localStorage.getItem("refreshToken");
    this.accountService.getNewToken(refreshToken).then(
      (res) => {
        if (res) {
          request = this._addToken(request, this.authService.getToken());
          return next.handle(request); // Don't perform the request intercepted 
        } else {
          this.router.navigate(["/login"]);
        }
      },
      (err) => {
        this.router.navigate(["/login"]);
      }
    );
  }

  _addToken(request: HttpRequest<any>, token: string) {
    return request.clone({
      setHeaders: {
        JWT_TOKEN: token,
      },
    });
  }
}

Solution

  • looks like you forgot return statement.

      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
          catchError((error) => {
            if (error instanceof HttpErrorResponse && error.status === 403) {
              return this._handle403Error(request, next);
            }
            return throwError(error);
          })
        );
      }
    
    _handle403Error(request: HttpRequest<any>, next: HttpHandler) {
        const refreshToken = localStorage.getItem("refreshToken");
        return from(this.accountService.getNewToken(refreshToken)).pipe(
            switchMap(res => {
                if (res) {
                    request = this._addToken(request, this.authService.getToken());
                    return next.handle(request); // Don't perform the request intercepted 
                }
                return from(this.router.navigate(["/login"])).pipe(switchMapTo(EMPTY));
            }),
            catchError(() => from(this.router.navigate(["/login"])).pipe(switchMapTo(EMPTY)),
        );
    }