I have a problem with my HttpInterceptor calling many times in a short period that it results in an error: RangeError: Maximum call stack size exceeded.
My HttpInterceptor is intercepting every request to add a bearer token to the header. The first time it passes the intercepter it will get the token from the authentication server this results in many POST calls to the authenticator in a short time. I guess this is that when it has no bearer token in the header the interceptor will make a call with HttpClient resulting in passing true the interceptor again and keeps calling GetAuthToken() resulting in looping until the error kicks in.
I have tried to ignore the request with a flag in the header but it still keeps looping. Do you have any suggestions how to cover this issue?
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('INTERCEPTOR');
// We retrieve the token, if any
const token = this.GetAuthToken();
let newHeaders = req.headers;
if (token) {
// If we have a token, we append it to our new headers
newHeaders = newHeaders.append('Authorization', "bearer " + token);
}
// Finally we have to clone our request with our new headers
// This is required because HttpRequests are immutable
const authReq = req.clone({headers: newHeaders});
// Then we return an Observable that will run the request
// or pass it to the next interceptor if any
return next.handle(authReq);
}
GetAuthToken(): any{
if (localStorage.getItem('access_token') != null){
return localStorage.getItem('access_token');
}
let httpHeaders = new HttpHeaders({
'Content-Type' : 'application/x-www-form-urlencoded'
});
let options = {
headers: httpHeaders
};
let body = `grant_type=${this.grant_type}&client_id=${this.client_id}&username=${this.username}&password=${this.password}`
this._http.post<AuthResponse>(this.url, body, options).subscribe(result => {
localStorage.setItem('access_token', result.access_token);
localStorage.setItem('refresh_token', result.refresh_token);
return result.access_token;
});
}
your interceptor intercep all, even your call in GetAuthToken, you need use an "if" to skip the call from GetAuthToken
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.body==`grant_type=${this.grant_type}&client_id=${this.client_id}&username=${this.username}&password=${this.password}`)
return next.handle(req);
...rest of your code..
}
You can also add a "fool header", like it's showed in this SO
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.headers.get("skip")){
const newHeader=req.headers.delete("skip");
const newreq= req.clone({headers: newHeaders});
return next.handle(newreq);
}
...rest of your code..
}
And in GetAuthToken()
GetAuthToken(){
...
let options = {
headers: httpHeaders.Add("skip",true)
};
...
}