HttpInterceptor with member-variables

47 views Asked by At

I made an interceptor-service for adding a auth-header to every HTTP-request.

Service

@Injectable ()
export class HttpInterceptorService implements HttpInterceptor
{
    token : string = undefined;
    
    setToken (token : string)
    {
        
        this.token = token;
        console.log ("interceptor set token", this.token);
    }
    
    intercept (req : HttpRequest <any>, next : HttpHandler) : Observable <HttpEvent <any>>
    {
        if (this.token != undefined)
        {
            console.log ("add token");
            let cloned : any = req.clone ({ headers: req.headers.append ("Authorization", this.token) });
            return next.handle (cloned);
        }
        else
        {
            console.log ("no token");
            return next.handle (req);
        }
    }
}

Module

...
providers: [
{
 provide: HTTP_INTERCEPTORS,
 useClass: HttpInterceptorService,
 multi: true
}
...

To avoid problems with cirtular injection I have setToken. But it is not working. Even if I set it, the token would still be undefined if called the next time by a HTTP-request.

What I need to do to have the token inside HttpInterseptorService saved between HTTP-calls?

1

There are 1 answers

0
spots On

Instead of making the interceptor stateful, I would create a service to manage the token and register it with the dependency injector. That way, you do not need to inject your interceptor somewhere it doesn't need to be.

The key here would be to make sure your service that manages the token is registered in the right scope, likely in root. Providing it in root ensures you have a single instance of the service available to the whole app, which means the token it exposes will always been the same.

@Injectable({providedIn: 'root'}) //or provided in app.module, or main.ts
export class DemoService {
  private _token: string | null = null;

  setToken(val: string) {
    this._token = val;
  }

  getToken() {
    return this._token;
  }
}


@Injectable()
export class DemoInterceptor implements HttpInterceptor {
  constructor(private demoSvc: DemoService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    //use the token from the service
    alert(`TOKEN: ${this.demoSvc.getToken()}`);

    return next.handle(req);
  }
}

Here's a working sample that demonstrates an interceptor using a service to get some token value.