Intercepting HTTP Requests to Include User Credentials in Angular
When sending a request to the server and the resource you are trying to access requires authorization, you would need to send a valid access token having the right permissions for the resource. If you use cookie authentication, you would need to pass a withCredentials = true to the options of the request in order to include the access token.
A sample get request would be:
this.http.get<string>(this.baseUrl + '/message/getMessage', { withCredentials: true }).subscribe((message: string) => { alert(message); });
We know that in every request, we would need to add withCredentials parameter; so, is there a way for us to automatically add this parameter when we invoke get or post? Fortunately, there is – using HttpInterceptor.
As the name suggests, an HttpInterceptor will intercept an HTTP request or response and execute certain lines of code before finally sending the request or process a response. HttpInterceptor would be very helpful for our case where we wanted to add withCredentials parameter on every request.
Create a class called AuthCredentialInterceptor with the following definition:
import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable() export class AuthCredentialInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const authReq = req.clone({ withCredentials: true }); return next.handle(authReq); } }
Our interceptor has a simple logic – clone our request, add a withCredentials parameter and process the cloned request.
Then, you would have to tell our app module to use this interceptor on every request:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthCredentialInterceptor } from './@core/http/auth.interceptor'; @NgModule({ // other attributes here providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthCredentialInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
Now, we can rewrite our original request without the need to specify the withCredentials parameter:
this.http.get<string>(this.baseUrl + '/message/getMessage').subscribe((message: string) => { alert(message); });