How to build an Http Interceptor in Angular Framework

How to build an Http Interceptor in Angular Framework

Introduction

Angular framework has become one of the most famous javascript frameworks in the last few years . In fact this tool contains many functionnalities and features which are very usefull for frontend web development .

In this article we are going to show you how to build an Http interceptor in Angular framework

What the hell is Http interceptor ?

First let's make this simple .

We all know that with Angular we can perform http requests to any server side based on REST approach using (GET,POST,PUT,DELETE) methods , thus in the modern web architectures dealing with http requests has become more and more complicated the fact that sometimes we have to add extra informations to the request before sending it to the server and we can take as an exemple RESTful webservices that use token based authentication as a security approach which is actually based on sending requests to the server and adding what we call an acces token in the header of the http request, after that the request will be intercepted by the server side middleware to check whether the token is valid or not and grant access to grab or persist data .

Now the problem is that we have to add this access token manually using special headers to every single http request in our Angular application and exactly in every service provider that we have where we usually use HttpClient to make requests .

To avoid this problem we are going to use Http interceptor which is a new feature included in Angular that help us to intercept http requests and attach automatically any extra information .

Getting started

To start we are going to create a new Angular application so you basically must have node Js and Angular CLI installed in your system .

To create a new projet open your command line and write this command

 ng new HttpInterceptorApp

now move under the project direcory and tape

ng serve 

open your browser and go to https://localhost:4200/ you will have this page displayed

At this point everything looks great .

Now what we are going to do exactly is that we will try to combine Angular and Node Js to make a simple authentication system in order to grab the access token from the server .

First clone this repository (https://gitlab.com/medaymen/JWTNodeJs) then move under the project directory and run (npm install) after that start the node js server using (node index.js)

if you want to know more about Token based authentication you can check our last tutorial in the link below : (https://www.dhirubhai.net/pulse/securing-your-node-js-api-json-web-token-mohamed-aymen-ourabi/) .

Now in angular application we are going to build a simple authentication system so go to app.component.html file and add these few lines .

<input type="text" name="username" id="username" [(ngModel)]="username">
<br>
<input type="password" name="password" id="password" [(ngModel)]="password">
<br>
<input type="button" value="Login" (click)="Login()">
<br>
<input type="button" value="Display list" (click))="DisplayList()" />

(Don't forget to add FormsModule in your app.module.ts )

So this is basically a simple HTML code in which we have two input text and two buttons one for the login and the other will be used to display a list of products that we are going to fetch form the server , so in order to do that we have to attach the token to the GET request before sending it to the server .

In our project and using the command line create a new service called Auth

Now create a file called interceptor.ts and add these few lines

import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from "@angular/common/http";
import { Observable } from "rxjs/Observable";

@Injectable()
export class Interceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      
    const customReq = request.clone({
    
    });

    return next.handle(customReq);
  }
}

Now go to app.module.ts file and import HttpClientModule , HTTP_INTERCEPTOR and interceptor so that your file will look like this

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms'
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { Interceptor } from './interceptor';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule

  ],
  providers: [
    AuthService,

    { provide: HTTP_INTERCEPTORS, useClass: Interceptor, multi: true }  
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Go back to your Auth.service.ts and create these two methods

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class AuthService {

  constructor(private Http:HttpClient) { }


  Authentication(username:string,password:string){
    let json = {username:username,password:password}
    return this.Http.post("https://localhost:3000/authenticate ",json); 
  }


  GetAllProducts(){
    return this.Http.get("https://localhost:3000/api/getAllProducts")
  }

   

}

To be honest ,in order to keep things well organized it is better to create another service in which you have to put GetAllProducts method but for this tutorial we will just keep it in the Auth service .

now in App.component.ts create two methods Login() and DisplayList() which will handle the click button events

import { Component } from '@angular/core';
import { AuthService } from './auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

 private username:string = ""

 private password:string = ""

       constructor(private authService:AuthService) {
         
       }

       Login(){
         this.authService.Authentication(this.username,this.password).subscribe(
           (data)=>{
           
            if(data["token"] != null){


              // retreive the access token from the server

           console.log(data["token"])


            // store the token in the localStorage 

            localStorage.setItem("access-token",data["token"])

           
            }else{
              console.log("check your credentials !!")
            }
           }
         )
       }

       DisplayList(){
         this.authService.GetAllProducts().subscribe(
           (data)=>{


              // display list in the console 

                 console.log(data)
           }
         )

       }
}

  

Now comes the best part !!

in order to attach the access token to every single http request we will update our interceptor.ts file so it will look like this

import { Injectable, Injector } from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders} from '@angular/common/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/observable/throw'
import 'rxjs/add/operator/catch';
@Injectable()
export class Interceptor implements HttpInterceptor {
  constructor() {}
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {


 if(localStorage.getItem('access-token') != null) 
{
   const token =  localStorage.getItem('access-token');

// if the token is  stored in localstorage add it to http header

const headers = new HttpHeaders().set("access-token", token);

   //clone http to the custom AuthRequest and send it to the server 


const AuthRequest = request.clone( { headers: headers});

return next.handle(AuthRequest)

   }else {
     return next.handle(request);
   }

  }
}

In our browser try to login using these credentials (aymen,123) , after that open your browser console so you can see that we have successfully logged in and we have our token

Now go to application ==> localstorage and you can see that the token is stored as well

Now let's try to display the list of product from the server, so click the button Display list and let's see what will happen


Everything looks fine the token is validated by the server middleware and we have our products displayed .

now to better have a look at what the interceptor did go to network and open the frame relative to getAllProducts request

we can see now that the interceptor has automatically added the access token to the header of the request note that this operation will be done for every single request that we are going to perform to our server using angular HttpClient service .

Conclusion

Http intrecptor is a very beautifull tool that helps us to customize our http requests and make any operations like adding custom headers or updating the data before it will be send to server , note that this is not the only feature provided by Angular but there are many tools which are equivalent to this and could be very usefull when building web applications

You can find the project in the link below : https://gitlab.com/medaymen/AngularHttpInterceptor




Mohamed Amine Garci

Développeur Android Sénior | Kotlin | Jetpack Compose

6 年

Great work ! but i think working with response status codes will be better in case you a have refresh tokens or tokens with a lifetime.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了