Dans vos applications, vous aurez très souvent besoin d'accomplir certaines tâches pour chaque requête HTTP envoyée par votre application. L'authentification, le logging, la gestion d'erreur – tout ça serait très lourd à implémenter manuellement pour chaque méthode de service.
Heureusement, l'équipe Angular a pensé à ce besoin, et a créé les intercepteurs. Comme leur nom l'indique, les intercepteurs interceptent toutes les requêtes envoyées (ainsi que les réponses reçues) par votre application, et vous permettent d'accomplir les tâches nécessaires.
Même si le serveur de développement de Snapface ne requiert pas d'authentification, vous allez implémenter un intercepteur qui viendra ajouter un header d'autorisation à chaque requête. Ce header contiendra un faux token que vous aurez stocké en dur dans un service. Vous utiliserez ensuite les DevTools de votre navigateur pour vérifier le bon fonctionnement de votre intercepteur.
Créez l'intercepteur
Un intercepteur est une classe TypeScript qui implémente l'interface HttpInterceptor et qui comporte le décorateur @Injectable()
.
Créez un dossier interceptors
dans le dossier app
, et créez-y un fichier auth.interceptor.ts
:
import { HttpInterceptor } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
}
Votre IDE doit être en train de vous embêter pour implémenter correctement l'interface HttpInterceptor. Pour ce faire, vous devez créer une méthode intercept()
avec l'empreinte suivante :
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
}
}
La méthode intercept()
sera appelée pour chaque requête et recevra cette requête comme argument, en plus d'un objet appelé next
que vous découvrirez dans un instant.
Avant d'implémenter cette méthode, préparez le service qui renverra le token. Dans le dossier services
, créez un service auth.service.ts
qui contient un token
privé sous forme de string
, et une méthode getToken()
qui la renvoie :
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private token = 'MyFakeToken';
getToken(): string {
return this.token;
}
}
De retour dans votre intercepteur, injectez le service que vous venez de créer, et implémentez la méthode intercept
comme suit :
import { HttpEvent, HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headers = new HttpHeaders()
.append('Authorization', `Bearer ${this.authService.getToken()}`);
const modifiedReq = req.clone({ headers });
return next.handle(modifiedReq);
}
}
Dans la méthode :
vous créez des
headers
utilisables par Angular avecnew HttpHeaders()
et vous utilisez leur méthodeappend()
pour y ajouter un headerAuthorization
qui contientBearer TOKEN
– c'est souvent la forme requise pour ce type de header ;vous créez une nouvelle requête en clonant la précédente et en y ajoutant les
headers
que vous venez de créer – les requêtes sont des objets immuables (qu'on ne peut pas modifier), donc on créera toujours une nouvelle requête qui contient les modifications requises ;vous retournez
next.handle()
en y passant la nouvelle requête – c'est ce qui permet à la requête de continuer son chemin.
Votre intercepteur est prêt : il faut maintenant l'enregistrer auprès d'Angular pour qu'il soit appelé pour chaque requête.
Enregistrez l'intercepteur
Puisqu'une application comporte généralement plusieurs intercepteurs, pour éviter de trop polluer AppModule on commence généralement par créer un fichier d'index qui prépare l'enregistrement de tous les intercepteurs au même endroit.
Dans le dossier interceptors
, créez un fichier index.ts
:
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';
export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
];
L'utilisation de HTTP_INTERCEPTORS
dit à Angular qu'il s'agit ici d'un intercepteur HTTP. Vous y attribuez la classe AuthInterceptor que vous venez de créer. La clé multi
prévient que vous allez certainement ajouter plusieurs intercepteurs à la clé HTTP_INTERCEPTORS
.
Il ne reste plus qu'à ajouter cette constante aux providers
de l'application. Dans AppModule :
// ...
import { httpInterceptorProviders } from './interceptors';
// ...
providers: [
{ provide: LOCALE_ID, useValue: 'fr-FR' },
httpInterceptorProviders
],
// ...
Et voilà, c'est terminé ! Pour vérifier que tout fonctionne, ouvrez l'onglet Network (Réseau) des outils de développeur de votre navigateur, cliquez sur la requête facesnaps, et dans les Request Headers sous l'onglet Headers vous trouverez :
Votre header a bien été ajouté à la requête ! Vous pouvez faire le test avec toutes les requêtes envoyées par l'application.
Et voilà ! L'intégration du serveur de backend dans votre application est terminée !
En résumé
Un intercepteur HTTP intercepte toutes les requêtes HTTP envoyées par votre application pour effectuer des tâches requises, comme l'ajout d'un header d'autorisation.
Un intercepteur Angular est une classe
@Injectable
qui implémente l'interface HttpInterceptor.La méthode
intercept()
clone la requête reçue en ajoutant les modifications requises au clone.intercept()
passe ensuite la nouvelle requête ànext.handle()
pour lui permettre de continuer son chemin.
Qu'avez-vous appris dans cette partie du cours ?
Vous avez ajouté HttpClientModule à votre application et injecté HttpClient à vos services pour pouvoir envoyer des requêtes HTTP ;
Vous avez découvert que les requêtes créées par HttpClient sont des Observables.
Vous avez utilisé les méthodes
get()
,post()
etput()
pour générer des requêtes GET, POST, et PUT ;Vous avez créé des requêtes simples pour récupérer les FaceSnaps, que ce soit la liste complète ou un par un – vous avez souscrit à ces Observables simples avec le pipe async pour afficher les réponses du serveur dans le DOM ;
Vous avez généré des requêtes composées sous forme d'Observables haut niveau, qui créent une nouvelle requête à partir de la réponse à une requête précédente – vous avez souscrit à ces Observables avec la méthode
subscribe()
dans vos components ;Vous avez mis en place un intercepteur qui ajoute un header d'autorisation à toutes les requêtes envoyées par votre application pour simuler un système d'authentification.
C'est l'heure d'un quiz sur toute cette partie ! Dans la prochaine et dernière partie du cours, vous découvrirez et implémenterez une architecture plus avancée avec les modules, le lazy loading et les guards.