Angular Interceptor: Adding Headers and Handling Token Expiry

Alex Onozor
alexonozor
Published in
3 min readNov 22, 2023

Angular interceptors are a powerful tool that enables developers to manipulate HTTP requests and responses globally. In this article, we’ll explore how to use Angular interceptors to add headers to outgoing requests and handle scenarios where a token has expired, redirecting the user to the login page.

Setting Up the Angular Project

Let’s start by creating a new Angular project using the Angular CLI. Open your terminal and run the following commands:

ng new angular-interceptor-demo
cd angular-interceptor-demo

Creating an Interceptor for Headers

We’ll first create an interceptor that adds a custom header to each outgoing HTTP request. Create a new file named header-interceptor.ts: code

import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HeaderInterceptor implements HttpInterceptor {
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const modifiedRequest = request.clone({
setHeaders: {
'X-Custom-Header': 'Custom Header Value',
},
});
return next.handle(modifiedRequest);
}
}

This interceptor uses the clone method to create a modified request with an additional custom header.

Creating an Interceptor for Token Expiry

Now, let’s create an interceptor to check for token expiry and redirect the user to the login page if necessary. Create a new file named token-interceptor.ts:

import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error) => {
if (error.status === 401) {
// Token expired, redirect to login page
this.router.navigate(['/login']);
}
return throwError(error);
})
);
}
}

In this interceptor, we use the catchError operator to intercept HTTP errors. If the error status is 401 (Unauthorized), we assume the token has expired and redirect the user to the login page using the Angular Router.

Registering the Interceptors

Now, let’s register these interceptors in the Angular module. Open the app.module.ts file:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { HeaderInterceptor } from './header-interceptor';
import { TokenInterceptor } from './token-interceptor';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpClientModule,
RouterModule.forRoot([]), // Add your routes here
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HeaderInterceptor,
multi: true,
},
{
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}

In the providers array, we provide instances of both HeaderInterceptor and TokenInterceptor. The multi: true option allows multiple interceptors.

Testing the Interceptors

You can now test the interceptors in your components. For example, make an HTTP request in your component:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
template: `
<button (click)="makeRequest()">Make Request</button>
`,
})
export class AppComponent {
constructor(private http: HttpClient) {}
makeRequest() {
this.http.get('https://jsonplaceholder.typicode.com/todos/1').subscribe(
(data) => {
console.log('Response:', data);
},
(error) => {
console.error('Error:', error);
}
);
}
}

Ensure you have defined routes in your application, including a route for the login page, so that the token interceptor can redirect the user when needed.

Conclusion

Angular interceptors are a valuable feature for handling HTTP requests and responses in a centralized and reusable manner. By creating interceptors for adding headers and handling token expiry, you can enhance the security and functionality of your Angular applications. These interceptors provide a clean and modular way to manage cross-cutting concerns in your HTTP communication.

--

--

Alex Onozor
alexonozor

Software Consultant, JavaScriptor, Web evangelist. Open source contributor. Software Architect.