¿Cómo implementar un Interceptor en Angular? Envió de token en la cabecera HTTP

Normalmente cuando queremos hacer peticiones a un API se requiere de un token de autorización o una api key. Varios desarrolladores optan por incluir la cabecera cada servicio o petición. Para no hacer esto tan tedioso existe una forma de hacer esto de manera mas sencilla utilizando HTTP INTERCEPTOR

¿Qué es un HTTP Interceptor?

Como lo indica su nombre Intercepta las peticiones y respuestas HTTP modificandolas si es necesario o inpeccionandolas.

Arquitectura Interceptor
Diagrama de funcionamiento

Generar HTTP Interceptor en Angular

Utilizando el CLI de Angular podemos utilizar el siguiente comando:

ng g s auth-interceptor

Una vez creado el servicio se implementa la interfaz HttpInterceptor y algunas clases extras que se encuentran en @angular/common/http.

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

@Injectable({
  providedIn: 'root'
})
export class AuthInterceptorService implements HttpInterceptor {

  constructor() {}
// Implementaciòn del metodo
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
  }

}

Supongamos que hacemos un login exitoso, el servicio del backend nos devuelve un token que debemos mandar en cada petición para poder consumir el servicio, el token se almacenara en el session storage.

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

@Injectable({
  providedIn: 'root'
})
export class AuthInterceptorService implements HttpInterceptor {

  constructor() {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    //Obtenemos el token del sessioStorage
    const token: string = sessionStorage.getItem('token');

    let request = req;
	//Validamos si el token existe
    if (token) {
      //Clonamos el token y lo mandamos en la cabecera de todas las peticiones HTTP
      request = req.clone({
        setHeaders: {
          //Autorizaciòn de tipo Bearer + token
          //El tipo de autorizaciòn depende del back
          authorization: `Bearer ${ token }`
        }
      });
    }
    return next.handle(request);
  }
}

Recordemos que los interceptors se ejecutan en cada petición que se realiza al servidor, pero para indicarle a Angular que queremos que haga esto con cada petición HTTP debemos registrarlo.

Registrar HTTP Interceptor

Para registrar un interceptor se tiene que indicar en el array de providers: [] en el módulo raíz, generalmente es AppModule. Importamos HTTP_INTERCEPTORS y luego proveemos el intercepetor

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

// Importaciòn de interceptor
import { AuthInterceptorService } from './auth-interceptor.service';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptorService,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Se coloca multi: true para permitir agregar más interceptors si se requiere y no sobre escribir el interceptor creado.

Con esto nuestro interceptor esta listo y modificara cada petición HTTP que se realice al servidor solamente si existe el token.

Proyecto de ejemplo

En el siguiente link encontraras un proyecto realizado con MEAN Stack (MongoDB, ExpressJS, Angular y NodeJS) donde básicamente es un login muy simple pero que nos sirve para ver el uso de los interceptors. En el repositorio del proyecto se encuentran las indicaciones de instalación.

LoginMean
Login con MEAN Stack

El backend en NodeJS con ExpressJS nos solicita un token para realizar cada petición que nos otorga el back cada vez que hacemos SignIn (Login) o hacemos SignUp (Registro).

El back espera un token de tipo “Bearer token

Desde el Frontend creamos un Interceptor donde .getToken() nos devuelve el token del session storage para luego modificar la petición

Token JWT
Token almacenado en el session storage

CONCLUSIÓN

Los interceptors nos ayudan a manipular las peticiones y respuestas HTTP facilitando el no hacer estas modificaciones en cada servicio, ademas con estos nos evitamos realizar una modificación en cada servicio en alguna circunstancia, aparte la mantenibilidad del código es mas sencilla.

Leave a Reply

Your email address will not be published.