user9364371
user9364371

Reputation:

Too much recursion on HttpInterceptor

In my application, the authentication is based on JWT tokens. In order to invalidate them, I've placed a random secure string inside of the JWT and the exact same string stored in the database, associated with the user who owns the token. These two have to match for the JWT to be valid. When the user logs out, the API generates another random string and replaces the old one on the database, making the JWT invalid for that user because the string inside de JWT and the string of the database don't match.

For this to happen, I need an interceptor that makes a silent request BEFORE every request to the API to check if the random strings are equal. Based on this question, my interceptor works but behaves weird, making infinite requests and throwing the "too much recursion" error.

What am I doing wrong?

Interceptor

 import { TokenService }     from './token.service';
 import { Router }           from '@angular/router';
 import { HttpInterceptor,
     HttpRequest, 
     HttpHandler, 
     HttpEvent, 
     HttpClient,
     HttpHeaders }       from "@angular/common/http";
 import { Injectable }       from "@angular/core";
 import { Observable }       from "rxjs/Observable";
 import { SharedService }    from "./shared-service.service";
 import { CookieService }    from 'ngx-cookie-service';

 @Injectable()

export class AuthInterceptor implements HttpInterceptor {


constructor(private sharedService : SharedService,
            private httpClient : HttpClient,
            private router : Router,
            private cookieService : CookieService,
            private tokenService : TokenService)  {}

token:          string;
cd:             number;
isExpired:      boolean = false;
revog_token:    string;

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

// Check if token exists on cookies
if(this.tokenService.CheckToken()){
    if (req.url.match(/api\//)) { // Request to API
       console.log("API Request");
       this.CheckRevogToken(); // <-- THIS METHOD TRIGGERS THE "TOO MUCH RECURSION" ERROR

    }
    const cloned = req.clone({ headers:  req.headers.set("Authorization","Bearer "+ this.tokenService.GetToken()) });
    return next.handle(cloned);
}
else{
    return next.handle(req).catch((error, caught) => { 
    // If status code is  401 ==> Not authorized
    if(error.status == 401){
        alert("A sua sessão expirou! Será redirecionado para a página de autenticação");
    }else{
        console.log("Ocorreu um erro");
        return Observable.throw(error);
    }}) as any;
  }
}   


CheckRevogToken(){
    this.revog_token = this.tokenService.GetRevogFromDecodedToken();
    var headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');
    return this.httpClient.post("http://localhost:53448/api/check_revog_token", {cd: this.cd, revog_token: this.revog_token}, {headers:headers})
.subscribe(
    res => {
      console.log(res); 
    },
    err => {
      console.log("err: " +err);
      }
  )};
 }   

Error screenshot

Error screenshot

Upvotes: 3

Views: 868

Answers (1)

Tinki
Tinki

Reputation: 1526

You have created infinite loop in your code:

  1. You start with: http://localhost:53448/api/... request

  2. Your HttpInterceptor catches it. Because url matches (/api\//) format, then this.CheckRevogToken() method is called

  3. In CheckRevogToken() you create a hearder, and post is to the following url:"http://localhost:53448/api/check_revog_token"

  4. Your post request is one more time caught by HttpInterceptor. Because url again matches (/api\//), then step 2 is repeated.

Upvotes: 4

Related Questions