55

I'm in the proces of adding an interceptor to my angular 6 project. To make calls to my API, I need to add a bearer token to all calls. Unfortunately the interceptor does not seem to be called. My code:

import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { Observable } from "rxjs";

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>,
              next: HttpHandler): Observable<HttpEvent<any>> {

        //Retrieve accesstoken from local storage
        const accessToken = localStorage.getItem("access_token");

        //Check if accesToken exists, else send request without bearer token
        if (accessToken) {
            const cloned = req.clone({
                headers: req.headers.set("Authorization",
                    "Bearer " + accessToken)
            });

            console.log('Token added to HTTP request');

            return next.handle(cloned);
        }
        else {
            //No token; proceed request without bearer token
            console.log('No token added to HTTP request');
            return next.handle(req);
        }
    }
}

Does anyone know what could be causing this issue? Thanks in advance.

Mikey123
  • 1,201
  • 2
  • 12
  • 23

11 Answers11

132

In my case interceptor wasn't getting involved for service calls because I had imported HttpClientModule multiple times, for different modules.

Later I found that HttpClientModule must be imported only once. Doc ref

Praveen Pandey
  • 1,675
  • 3
  • 13
  • 17
  • 4
    thanks !! been trying to resolve this issue for 2 days straight... it was multiple imports of HttpClientModule – Datum Geek Oct 29 '20 at 09:41
  • 2
    Spot on! Make sure that you do not import it twice or more. Check your shared module as well, in case you import any in your App Module. That was the issue for me, at least :) – Server Khalilov Mar 31 '21 at 22:51
  • 1
    This can also happen if the Service for which you want to intercept requests is (unnecessarily) added to the provided attribute of some (sub)module. Removing it from the list of provided services made the HttpInterceptor work again. – xaviert Apr 28 '21 at 07:24
47

You use the right way to intercept.

For people who use interceptor, you need to do 2 modifications :

Interceptor in service

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse }
  from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {

    return next.handle(req).do(evt => {
      if (evt instanceof HttpResponse) {
        console.log('---> status:', evt.status);
        console.log('---> filter:', req.params.get('filter'));
      }
    });

  }
}

Provide HTTP_INTERCEPTOR

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
(...)
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true }
  ],

Read this article for more details. It's pretty good

Liam
  • 27,717
  • 28
  • 128
  • 190
Pterrat
  • 1,682
  • 11
  • 18
  • 3
    Keep in mind that rxjs has changed a lot. do operator now is called tap and needs to be used within a pipe() https://www.academind.com/learn/javascript/rxjs-6-what-changed/ – Dukeatcoding Jan 27 '20 at 10:58
  • 1
    This is really quite out of date now – Liam Jun 03 '20 at 08:10
8

If you have a providers array for a module then you have to define the HTTP_INTERCEPTORS too for that module then only it will intercept the requests under that module.

e.g:

providers: [ 
// singleton services
PasswordVerifyService,
{ provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptorService, multi: true }
]
Ajit Das
  • 79
  • 1
  • 2
3

In my case, I had to import both HTTP_INTERCEPTORS, HttpClientModule in same module.

M Faisal Hameed
  • 673
  • 1
  • 7
  • 25
  • 4
    if you add `HttpClientModule` & `HTTP_INTERCEPTORS` in your parent module then you'll not need to import these two in your sub-modules. – WasiF Nov 19 '20 at 16:58
  • 1
    Same for me. Does it mean I can't add interceptors only for some child modules? – Ilya Loskutov Jun 08 '23 at 08:01
2

In my case i had a post method like this:

this.http.post<any>(this.authUrl, JSON.stringify({username: username, password: password})).pipe(
      map((response: any) => {
            let token: any = response.token;
            if (token) {
                localStorage.setItem('currentUser', 'value' }));                
                return response; 
            } else {
                return null;
            }
        }),
        catchError((error:any) => {return observableThrowError(error.json().error || 'Server error')})
      );

Because the map method could return null the interceptor stopped intercepting the requests made with this post method call. Don't ask me why this is so, but as soon as i replace null with say response everything started working again.

Maurice
  • 6,698
  • 9
  • 47
  • 104
2

Check your module & sub-module files, If you have imported the interceptor in a sub-module, then move it to the root module and it should work.

Community
  • 1
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/31842694) – Sumit Sharma May 28 '22 at 13:17
2

I had the exact same behavior with my standalone component (interceptors not intercepting my http requests).

If you use standalone components instead of importing HttpClientModule in your Module, note that you have to add withInterceptorsFromDi() in your provideHttpClient(...) to make your interceptors work! Or use the new way of functional interceptors via withInterceptors.

See this SO post for more details.

andymel
  • 4,538
  • 2
  • 23
  • 35
1

In my case the HttpClient was not used to do the requests.

Instead fetch has been used directly and that is not intercepted by angular.

Changed fetch(...) to http.get(...) and it worked

andymel
  • 4,538
  • 2
  • 23
  • 35
0

In my case I accidentally had my service proivded providers : [ ApplicationService ] in my component when it wasn't supposed to be as I had it defined using providedIn: 'root'

0

Please ensure that dependencies for the interceptor are also provided in the module. ProvidedIn:'root' for the interceptor dependency services did not work for me.

0

In my case, since I am working with modules, I had to import the child module (AuthModule) in app.module.ts. I was just missing that.

imports: [ HttpClientModule, AppRoutingModule, AuthModule ]