HTTP Interceptor not working with service call

336 Views Asked by At

I have created an interceptor to add header, so that I don't have to manually add header to each http request. But the moment I add service call inside my interceptor it wouldn't trigger, I am not sure why. Below is my code.

Here is my interceptor file

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, from } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { GoogleAuthService } from './services/auth/auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private authService: GoogleAuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('Interceptor: Intercepting request...');
    
    return this.authService.requestToken().pipe(
      switchMap(token => {
        console.log('Interceptor: Token obtained -', token);
        const authRequest = this.addAuthenticationToken(request, token);
        return next.handle(authRequest);
      })
    );
  }

  addAuthenticationToken(request: HttpRequest<any>, token: string) {
    return request.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });
  }
}

it prints the first console.log('Interceptor: Intercepting request...');, but never gets inside the service call to print the second console.log('Interceptor: Token obtained -', token);

Here is my service file

This function makes a request to GCP cloud function by passing target URL which returns a token which I want to pass to my interceptor

import { Injectable, SkipSelf } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, catchError, throwError } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class GoogleAuthService {
  audience = 'https://cloud.run.app';

  constructor(private http: HttpClient) {}

  requestToken(): Observable<any> {
    const requestUrl = "https://us-central1-gcp.cloudfunctions.net/get-token"
    const tokenUrl = `${requestUrl}?url=${this.audience}`
    return this.http.get(tokenUrl)
  }
}

This is working fine, if I don't make any service call and hardcode the token as below, the problem shows up when I make service call to get the token

import { Injectable, SkipSelf } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpClient } from '@angular/common/http';
import { Observable, from, tap } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { GoogleAuthService } from './services/auth/auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  token: string = "5dadbb1d-03fc-11ed-baea-7640edfdd6b4";
  constructor(private httpClient: HttpClient, private authService: GoogleAuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(this.addAuthenticationToken(request));
  }

  addAuthenticationToken(request: HttpRequest<any>) {
    return request.clone({
      setHeaders: {
        Authorization: `Basic ${this.token}`
      }
    })
  }
}

Here is my module file

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

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { GoogleAuthService } from './services/auth/auth.service';
import { AuthInterceptor } from './auth.interceptor';

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

Here is the browser window screenshot

enter image description here

1

There are 1 best solutions below

4
Matthieu Riegler On

You interceptor should skip the call to the service when it's the service himself that is making the request.

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  token: string = "5dadbb1d-03fc-11ed-baea-7640edfdd6b4";
  constructor(private httpClient: HttpClient, private authService: GoogleAuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if(request.url.includes('get-token') {
      return next.handle(request);
    } 

    return next.handle(this.addAuthenticationToken(request));
  }

  addAuthenticationToken(request: HttpRequest<any>) {
    return request.clone({
      setHeaders: {
        Authorization: `Basic ${this.token}`
      }
    })
  }
}