Implementing Token Interceptor and Retry in Angular 4

If you are building a web application using Angular 4 or Angular 5 there’s a good chance that you might be working with JWT tokens. Luckily, implementing token interceptor and retry in Angular 4 and beyond is very easy thanks to the new HTTP Interceptors. Using this, we can add an authorization header to every outbound request while also implementing a retry mechanism for requests that fail due to an expired token. Let’s walk through the code.

App Module

The first thing that you need to do is implement the interceptors in the App module.

providers: [
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true

Note that the useclass property will be the imported class that uses your TokenInterceptor.

Auth Service

We are going to first create a service that’s going to be responsible for retrieving our JWT access token and JWT refresh token. Note that we are making use of the angular JWT library.

import { tokenNotExpired, JwtHelper } from 'angular2-jwt';


export class AuthService {

jwtHelper: JwtHelper = new JwtHelper();

constructor(private http: HttpClient) {


public getToken(): string {

return localStorage.getItem('access_token');


public getRefreshToken(): string {

return localStorage.getItem('refresh_token');


public getNewAcessToken() {

return, { 'RefreshToken': this.getRefreshToken() });


Token Interceptor Class

Now let’s write the token interceptor class.

import { Injectable, Inject, Injector } from '@angular/core';

import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse, HttpErrorResponse } from '@angular/common/http';

import { AuthService } from './auth.service';

import { LoaderService } from './loader.service';

import 'rxjs/add/operator/do';

import 'rxjs/add/operator/catch';

import { Observable } from 'rxjs/Observable';

import { Router } from '@angular/router';


export class TokenInterceptor implements HttpInterceptor {

  public cachedRequests: Array = [];

  constructor(private router: Router, public inj: Injector, public loaderInject: Injector) { }

  private applyCredentials = (req: HttpRequest, token: string) => {
    return req.clone({
      setHeaders: {

        Authorization: token


  intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent> {

    const auth = this.inj.get(AuthService);

    const authReq = this.applyCredentials(req, auth.getToken());

    return next.handle(authReq)

      .map((event: HttpEvent) => {

        if (event instanceof HttpResponse) {

          return event;



      .catch((error: any) => {

        if (error instanceof HttpErrorResponse) {

          if (error.status === 401) {


            return auth


              .flatMap((res) => {

                localStorage.setItem('access_token', (res as any).Token);

                return next.handle(this.applyCredentials(req, auth.getToken()));


          } else if (error.status === 403) { //log back in!!



        } else {

          return Observable.throw(error);





Here’s the flow: Upon every request, the token interceptor is calling the apply credentials functions which appending an authorization header to every request. This header contains the access token. If a request fails with a 401, we can assume that the token has expired. Therefore, we are grabbing a fresh token from our auth service and retrying the failed request with the new token. If we get a 403, then we can assume that the access token failed and the user needs to log back in.

See also