HttpInterceptor上的递归过多

时间:2018-08-21 09:25:09

标签: typescript angular5 interceptor

在我的应用程序中,身份验证基于JWT令牌。为了使它们无效,我在JWT内放置了一个随机的安全字符串,并在数据库中存储了与拥有令牌的用户相关的完全相同的字符串。这两个必须匹配才能使JWT有效。 当用户注销时,API会生成另一个随机字符串,并替换数据库上的旧字符串,从而使JWT对该用户无效,因为de JWT内的字符串与数据库的字符串不匹配。

为此,我需要一个拦截器,该拦截器会在对API的每个请求之前发出一个静默请求,以检查随机字符串是否相等。 基于this问题,我的拦截器可以正常工作,但是行为却很怪异,提出了无限个请求,并引发了“递归过多”错误。

我在做什么错了?

拦截器

 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

1 个答案:

答案 0 :(得分:3)

您已在代码中创建了无限循环:

  1. 您先从:http://localhost:53448/api/...请求

  2. 您的HttpInterceptor抓住了它。由于url与(/api\//)格式匹配,因此会调用this.CheckRevogToken()方法

  3. CheckRevogToken()中,您创建了一个听众,并将帖子发布到以下网址:"http://localhost:53448/api/check_revog_token"

  4. 您的发帖请求还被HttpInterceptor捕获了一个时间。由于url再次与(/api\//)匹配,因此重复步骤2。