Thursday, January 12, 2023

Angular - HTTP interceptor

Introduction:

In Angular, an interceptor is a middleware that can be used to modify or intercept HTTP requests or responses before they are handled by the application.

To implement the HttpInterceptor interface provided by the @angular/common/http module. This interface requires implementing a single method called intercept, which takes in an HttpRequest object and a HttpHandler, and returns an Observable of HttpEvent.

By official documentation

Methods


intercept()


Identifies and handles a given HTTP request.

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

Parameters


req HttpRequest<any> The outgoing request object to handle.

next HttpHandler The next interceptor in the chain, or the backend if no interceptors remain in the chain.

Returns


Observable<HttpEvent<any>>: An observable of the event stream.


Usage





I used jsonplaceholder fake json. Get, Post, Put, Patch and Delete, it is common to use OAuth2 token for to access backend app from angular frontend, so it is need to add next header. 

const clonedRequest = req.clone({
      headers: req.headers.set('Authorization'`Bearer ${token}`),
    });

Before to send to backend request. 


Auth Service (fake token)


Real token we will get from Open Source Identity and Access Management, Basic Auth or something like that.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  public get token(): string {
    return '123456';
  }
}


Interceptor Service


Method called intercept that takes in two arguments: req: HttpRequest<any> and next: HttpHandler. Within the intercept method,  adding headers. After modifying the request, call the next.handle(req) method to continue with the request.

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent,
from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from '../auth.service';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  constructor(private authAuthService) {}

  intercept(
    reqHttpRequest<any>,
    nextHttpHandler
  ): Observable<HttpEvent<any>> {
    const token = this.auth.token;
    // Clone the request and add the new header
    const clonedRequest = req.clone({
      headers: req.headers.set('Authorization'`Bearer ${token}`),
    });

    // Pass the cloned request instead of the original request to the next handle
    console.log(clonedRequest);
    const keys = clonedRequest.headers.keys();
    alert(
      'Before request new header is added: \n' +
        keys.map((keyany=> `${key}${clonedRequest.headers.get(key)}`)
    );

    return next.handle(clonedRequest);
  }
}




HTTP Request Service


import { Injectable } from '@angular/core';
import { HttpClientHttpResponseHttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

const headers = new HttpHeaders().set(
  'content-type',
  'application/json; charset=UTF-8'
);
const endpoint = 'https://jsonplaceholder.typicode.com/posts';

@Injectable()
export class MyServiceService {
  constructor(private httpHttpClient) {}

  postData(dataany): Observable<HttpResponse<any>> {
    return this.http.post<any>(`${endpoint}`data, { headers: headers });
  }

  getData(idnumber): Observable<HttpResponse<any>> {
    return this.http.get<any>(`${endpoint}/${id}`);
  }

  updateData(dataanyidnumber): Observable<HttpResponse<any>> {
    return this.http.put<any>(`${endpoint}/${id}`data, { headers: headers });
  }

  patchData(dataanyidnumber): Observable<HttpResponse<any>> {
    return this.http.patch<any>(`${endpoint}/${id}`data, {
      headers: headers,
    });
  }

  deleteData(idnumber): Observable<HttpResponse<any>> {
    return this.http.delete<any>(`${endpoint}/${id}`);
  }
}



Component


import { ComponentVERSION } from '@angular/core';
import { MyServiceService } from './services/myservice/my-service.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'HTTP interceptor';
  constructor(private _serviceMyServiceService) {}

  responseboolean;
  datastring;

  onGet(valueboolean) {
    this.response = value;
    this._service.getData(1).subscribe((dataany=> {
      this.data = data;
    });
  }

  onSave(valueboolean) {
    this.response = value;
    let json = JSON.stringify({
      title: 'foo',
      body: 'bar',
      userId: 1,
    });

    this._service.postData(json).subscribe((dataany=> {
      this.data = data;
    });
  }

  onPut(valueboolean) {
    this.response = value;

    let json = JSON.stringify({
      id: 1,
      title: 'foo',
      body: 'bar',
      userId: 1,
    });

    this._service.updateData(json1).subscribe((dataany=> {
      this.data = data;
    });
  }

  onPatch(valueboolean) {
    this.response = value;
    let json = JSON.stringify({
      title: 'foo',
    });

    this._service.patchData(json1).subscribe((dataany=> {
      this.data = data;
    });
  }

  onDelete(valueboolean) {
    this.response = value;
    this._service.deleteData(1).subscribe((dataany=> {
      this.data = data;
    });
  }
}




Test






















Here integration example Spring Boot, Angular, Ldap and Keycloak.

Source Code

Here on stackblitz.


References

https://angular.io/
https://jsonplaceholder.typicode.com/






No comments:

Post a Comment

Deploying a Spring Boot Application with Cloud SQL and Cloud Run on GCP

In this post, we'll explore how to provision Cloud SQL instances with different connectivity options using Terraform and then access the...