In modern online applications, authentication is critical for safeguarding resources and guaranteeing that only authorized users have access to specified areas of the program. Tokens, such as JSON Web Tokens, are a typical method for handling authentication. Angular's HTTP interceptors allow you to send a token with each HTTP request in your application.

What is an HTTP interceptor?
In Angular, an HTTP interceptor is a middleware component that intercepts HTTP requests and answers. It allows you to alter requests or responses before they are delivered or received by the program. This functionality is useful for a variety of activities, including header addition, logging, error handling, and more.

Let's walk over the stages of implementing token-based authentication in an Angular application with an HTTP Interceptor.

Step 1: Create an HTTP Interceptor Service
First, establish a new Angular service to manage the HTTP Interceptor. To generate the service, open a terminal or command prompt and run the Angular CLI.

ng generate interceptor auth-interceptor

Step 2. Implement the Interceptor Logic
Open the auth-interceptor.service.ts file and implement the interceptor logic. Here's an example implementation.
import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpEvent,
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // Get the token from localStorage
    const token = localStorage.getItem('token');

    // Clone the request and add the token to the headers if it exists
    if (token) {
      const authReq = req.clone({
        setHeaders: { Authorization: `Bearer ${token}` },
      });
      return next.handle(authReq);
    }

    // If there's no token, just pass the original request
    return next.handle(req);
  }
}


In this code, we retrieve the token from the browser's local storage and add it to the authorization header of the HTTP request if it exists.

Step 3. Provide the Interceptor

Next, provide the interceptor in your Angular module (usually app.module.ts) as a provider. Here's an example of how to do it.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppComponent } from './app.component';
import { AuthInterceptor } from './auth-interceptor.service';

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


By providing the interceptor using the HTTP_INTERCEPTORS token, Angular will use our AuthInterceptor to intercept outgoing HTTP requests.

Step 4. Use HttpClient to Make Requests

Now that the interceptor is set up, you can use Angular's HttpClient service to make HTTP requests throughout your application. The interceptor will automatically add the token to the headers of these requests.

Here's an example service (data.service.ts) that uses HttpClient.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class DataService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get('https://dummyjson.com/products');
  }

  postData(data: any) {
    return this.http.post('https://dummyjson.com/post', data);
  }
}


In this example, when you call getData() or postData(), the interceptor will automatically add the authorization header with the token before sending the request.