Angular Authentication Using the HTTP Client and HTTP Interceptors

Angular HTTP Interceptors

Angular 9 is here. Angular 4.3 comes a brand new set of HTTP tools with a bunch of useful features. Perhaps the most long-awaited feature addition is the HttpInterceptor interface. Until now, there was no way to intercept and modify HTTP requests globally. This has always been possible in AngularJS and the fact that it has been lacking in Angular 2+ has been a sticking point with developers. In this Article we are going to Deal with HTTP Interceptors.

For Video Tutorials Subscribe my YouTube Channel

So why are HTTP Interceptors useful? There are many reasons, but one common use case is to automatically attach authentication information to requests. This can take several different forms but most often involves attaching a JSON Web Token (or other form of access token) as an Authorization header with the Bearer scheme.

Angular Http Interceptors

Let’s take a look at how to use Angular’s HttpInterceptor interface to make authenticated HTTP requests.

Make an Authentication Service

When handling authentication in an Angular app, it’s generally best to put everything you need in a dedicated service. Any authentication service should have a few basic methods for allowing users to log in and log out. It should also include a method for retrieving a JSON Web Token from wherever it is stored on the client and a way to determine if the user is authenticated or not.

This article assumes you already have an authentication setup in place and that you are storing JWTs in local storage. We won’t get into a full details here.

One way we can check whether a JWT is expired is to use angular2-jwt to return a boolean after checking the exp claim.

npm i --save angular2-jwt

After installing angular2-jwt, use it in a service.

// src/app/auth/auth.service.tsimport { Injectable } from '@angular/core';
import decode from 'jwt-decode';@Injectable()
export class AuthService { public getToken(): string {
return localStorage.getItem('token');
} public isAuthenticated(): boolean {
// get the token
const token = this.getToken();
// return a boolean reflecting
// whether or not the token is expired
return tokenNotExpired(null, token);

Create an Interceptor

The goal is to include the JWT which is in local storage as the Authorization header in any HTTP request that is sent. The first step is to create an interceptor. To do this, create an Injectable class which implements HttpInterceptor.

// src/app/auth/token.interceptor.tsimport { Injectable } from '@angular/core';
import {
} from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { Observable } from 'rxjs/Observable';@Injectable()
export class TokenInterceptor implements HttpInterceptor { constructor(public auth: AuthService) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.auth.getToken()}`
}); return next.handle(request);

Any interceptor that we want to create needs to implement the HttpInterceptor (HTTP Interceptors)interface. This means that our new class must have a method called intercept with HttpRequest and HttpHandler parameters. Using interceptors is all about changing outgoing requests and incoming responses, but we can’t tamper with the original request–it needs to be immutable. To make changes we need to clone the original request.

As we clone the original request we can set the headers we want. In our case its very simple–we just want to add an Authorization header with an auth scheme of Bearer followed by the JSON Web Token in local storage which we get from a call to the getToken method from the AuthService.

Calling next.handle means that we are passing control to the next interceptor in the chain, if there is one.

Add the Interceptor to Providers

The HTTP Interceptor needs to be added to the HTTP_INTERCEPTORS array. This is done by making the existing HTTP_INTERCEPTORS array use the new class we’ve created. Add this in the providersarray for our application’s module.

// src/app/app.module.tsimport { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './../auth/token.interceptor';@NgModule({
bootstrap: [AppComponent],
imports: [...],
providers: [
useClass: TokenInterceptor,
multi: true
export class AppModule {}

Now when we make any HTTP request, the user’s token will be attached automatically.

// src/app/ping/ping.component.tsimport { HttpClient } from '@angular/common/http';
// ...
export class AppComponent { constructor(public http: HttpClient) {} public ping() {
data => console.log(data),
err => console.log(err)

This request will include an Authorization header with a value of Bearer ey....

It should be noted that Angular’s new HttpClient from @angular/common/http is being used here and not the Http class from @angular/http. If we try to make requests with the traditional Httpclass, the interceptor won’t be hit.

For Video Tutorials Subscribe my YouTube Channel

Looking for Unauthorized Responses

When tokens expire we will generally get a 401 Unauthorized response back from the server. This gives us an indication that we need the user to log in again to get a new token.

We have some choices to make at this point. Do we want to redirect to a specific route that has a login form? Do we want to show a modal? Do we want to attempt to refresh the token?

Either way, we need to set up the intereptor to handle responses. The intercept method returns an observable which means we can capture the success and error channels for a response and operate on them however we like. This is the perfect place to do any kind of logging we might want to do. We can also check for 401 Unauthorized responses and prompt the user to log in again.

// src/app/auth/jwt.interceptor.ts// ...
import 'rxjs/add/operator/do';export class JwtInterceptor implements HttpInterceptor { constructor(public auth: AuthService) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff with response if you want
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
// redirect to the login route
// or show a modal

This is also a great spot to cache any failed requests. This comes in handy if we have token refreshing in place and we want to retry the requests once we have a new token.

// src/app/auth/auth.service.tsimport { HttpRequest } from '@angular/common/http';// ...
export class AuthService {cachedRequests: Array<HttpRequest<any>> = [];public collectFailedRequest(request): void {
}public retryFailedRequests(): void {
// retry the requests. this method can
// be called after the token is refreshed

The collectFailedRequests method can now be used in the interceptor.

// src/app/auth/jwt.interceptor.ts// ...
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff with response if you want
}, (err: any) => {
if (err instanceof HttpErrorResponse {
if (err.status === 401) {

With this in place, we have the option of calling retryFailedRequests after the user’s token is refreshed to fire off the previously-failed requests. This is just a small addition that can help to greatly improve UX, especially if you have tokens with a very short lifetime.

Related: Angular Routers

For Video Tutorials Subscribe my YouTube Channel