Reputation:
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
Upvotes: 3
Views: 868
Reputation: 1526
You have created infinite loop in your code:
You start with: http://localhost:53448/api/...
request
Your HttpInterceptor
catches it. Because url matches (/api\//)
format, then this.CheckRevogToken()
method is called
In CheckRevogToken()
you create a hearder, and post is to the following url:"http://localhost:53448/api/check_revog_token"
Your post request is one more time caught by HttpInterceptor
. Because url again matches (/api\//)
, then step 2 is repeated.
Upvotes: 4