HttpInterceptor-> Service-> HttpClient Cyclic Dependency

[SOLVED]

I solved this by manually entering AuthService into the AuthInterceptor, as suggested by this comment on a similar GitHub issue .

If the methods that you use from AuthService (or whatever) in your HttpInterceptor have made HTTP requests, make sure that you check outgoing requests in your interceptor to intercept only those that need authentication (i.e. : avoid infinite recursion when your requests to authentication endpoints are intercepted and so on ...)

Example:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // Ignore if login or refresh request if (req.url.includes('login')) { return next.handle(req); } const authService: AuthService = this.inj.get(AuthService); return authService.getCurrentToken().concatMap(token => { if(token) { const authHeader = 'Bearer ' + token; const authReq = req.clone({setHeaders: {Authorization: authHeader}}); return next.handle(authReq); } return next.handle(req); }); } 

So, I have an AuthService authentication service , which basically has two methods: one that receives a new token from the server, taking into account the username and password, and one that retrieves the currently saved token and updates the tokens during the process, if necessary. Both explicitly rely on HttpClient. That is, AuthService has a dependency on HttpClient. Remember this.

Another β€œservice” is the HttpInterceptor, which I want to intercept all outgoing requests other than those made by AuthService in order to add an authorization header (now it becomes dirty). And to compile this header, we need the token that we get from AuthService . That is, AuthInterceptor (the name of my interceptor) has a dependency on AuthService . And as far as I know, HttpClient has a dependency on all HTTP_INTERCEPTORS.

So the scenario is as follows: Cyclic dependence

Any ideas or suggestions on how to break this circle? Is there a way to make AuthService HttpClient independent of AuthInterceptor ? Or is this a bad idea? (Another third function will be added to AuthService for the user to enter the system whose requests should be intercepted, as well as the authorization header added to them)

So far I have found a similar issue , but the workaround suggested there does not solve my problem, now I get infinite recursion during the boot process before sending any requests. I handled the case of intercepting registration requests and token to avoid this , so this is not a problem here as far as I know. Here's a plunk with an overview of my code.

Excerpt from plunk:

 @Injectable() export class AuthInterceptor implements HttpInterceptor { private auth: AuthService; constructor(inj: Injector) { this.auth = inj.get(AuthService); } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // Ignore if login or refresh request if (req.url.includes('login')) { return next.handle(req); } console.log('Intercepting request...'); return this.auth.getToken().map(token => { const authHeader = 'Bearer ' + token; const authReq = req.clone({setHeaders: {Authorization: authHeader}}); return authReq; }).concatMap(newReq => next.handle(newReq)); } } 
+5
source share
2 answers

Try setting this.auth with a timeout:

 constructor(private injector: Injector) { setTimeout(() => { this.auth = this.injector.get(AuthService); }) } 

The error report that you contacted has since been updated, with an alternative workaround (getting AuthService in the hook function / and not setting it in the constructor): https://github.com/angular/angular/issues/18224# issuecomment-316957213

+5
source

Update 08/02/2018 - angular 5.2.3

Just update this: this has been fixed in angular 5.2.3

https://github.com/angular/angular/blob/master/CHANGELOG.md#bug-fixes-2

This way, it can directly inject HttpClient dependent services into HttpInterceptors

 @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private auth: AuthService) 
+2
source

Source: https://habr.com/ru/post/1270012/


All Articles