Angular HttpInterceptor范围错误: Maximum call stack size exceeded

标签 angular access-token angular-httpclient bearer-token angular-http-interceptors

我的 HttpInterceptor 在短时间内多次调用时遇到问题,导致出现错误:RangeError:超出最大调用堆栈大小。

我的 HttpInterceptor 正在拦截每个请求以将不记名 token 添加到 header 。第一次通过拦截器时,它将从身份验证服务器获取 token ,这会导致短时间内对身份验证器进行多次 POST 调用。我想这是因为,当 header 中没有承载 token 时,拦截器将使用 HttpClient 进行调用,从而再次传递 true 拦截器,并继续调用 GetAuthToken() 导致循环,直到出现错误.

我尝试忽略 header 中带有标志的请求,但它仍然不断循环。您对如何解决这个问题有什么建议吗?

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;
    });
  }

You see the console.log("INTERCEPTOR") many times from the interceptor method

最佳答案

你的拦截器拦截所有,甚至你在 GetAuthToken 中的调用,你需要使用“if”来跳过 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..
  }

您还可以添加一个“傻瓜 header ”,如 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..
  }

在 GetAuthToken() 中

GetAuthToken(){
   ...
   let options = {
      headers: httpHeaders.Add("skip",true)
    };
   ...
}

关于 Angular HttpInterceptor范围错误: Maximum call stack size exceeded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64983499/

相关文章:

php - Angular 6 HttpClient 和 PHP 错误 (unknown url) : 0 Unknown Error 的 Http 失败响应

Angular 4 - '.ts' 文件中文本的 ionic 3 翻译

Angular 5 表单重复输入值

Spring OAuth2 - 创建访问 token

angular - 为什么大多数 HttpClient API 类都定义不可变对象(immutable对象)?

angular - 将可选的查询字符串参数传递给 http 服务调用

与初始状态相同时,Angular 形成脏

javascript - 当页面变得可滚动时显示转到顶部按钮

javascript - 这个 javascript oauth 调用可以在 POSTMAN 中表示吗? (或c#)

c# - 生产服务器上的 ASP.NET Identity session 过期过快