Angular 订阅无限循环

Angular 订阅无限循环,angular,Angular,我试图在auth.interceptor.ts中刷新JWT令牌时捕获一个坏请求(400),因为刷新令牌应该在某个时间过期。您可以查看下面的代码片段,但我也会提供StackBlitz 当我在中返回这个.authService.logout()时,问题来自catchError。它运行在一个无限循环中,因为当我返回next.handle(请求)时在switchMap中,它继续执行用户未被授权的/api/values(实际请求),并引发另一个错误。当我做return-throwError(错误)时也是如

我试图在
auth.interceptor.ts
中刷新JWT令牌时捕获一个坏请求(400),因为刷新令牌应该在某个时间过期。您可以查看下面的代码片段,但我也会提供StackBlitz

当我在
中返回这个.authService.logout()
时,问题来自
catchError
。它运行在一个无限循环中,因为当我
返回next.handle(请求)时
在switchMap中,它继续执行用户未被授权的
/api/values
(实际请求),并引发另一个错误。当我做
return-throwError(错误)时也是如此。这就是无限循环发生的地方。我确实必须订阅
this.authService.logout()
,因为在我注销用户之后,我将从我的数据库(HTTP post)中撤销他的刷新令牌。你可以在StackBlitz上看到整个代码

return this.authService.refreshToken()
    .pipe(
      switchMap(token => {
        console.log('Token refreshed.');
        return next.handle(this.attachTokenToRequest(request, token));
      }),
      catchError(error => {
        return this.authService.logout()
          .pipe(
            switchMap(result => {
              console.log(result);
              return throwError(error); // request = /api/values, error = /api/refresh/token
              // return next.handle(request);
            })
          )
      })
    );
除了上面的内容之外,我尝试用下面的代码捕获错误代码400,但基本相同

if (error.status === 400 && error.error === "Cannot find that refresh token." || error.error === "Expired refresh token.") {
  console.log('400 bad request');
  return this.authService.logout()
    .pipe(
      switchMap(error => {
        return Observable.throw(error); // this should be replaced, maybe?
      })
    );
}
如上所述,我知道问题是什么。我不知道怎么解决它。我想捕获刷新令牌何时过期或不再存在,然后注销用户并导航到登录页面。我该怎么做

您需要向后端服务器绕过拦截器发出注销请求。因此,您可以使用
HttpBackend
创建一个新的
HttpClient
,并在不希望拦截器干扰请求时使用它

@Injectable()
导出类身份验证服务{
私有后端客户端:HttpClient;
公共构造函数(私有httpClient:httpClient,处理程序:HttpBackend){
this.backendClient=新的HttpClient(处理程序);
}
//此API使用拦截器
公共刷新令牌(){
返回此.httpClient.get(…);
}
//此API不使用拦截器
公共注销(){
返回此.backendClient.get(…);
}
}

使用“如果”,不要拦截注销?真是太棒了!这是专业人士推荐的方式吗?我还想抑制400错误请求错误。因此,我让catchError返回
returnnext.handle(请求),它删除了错误消息,但HTTP侦听器中有一个模式窗口。我在HTTP拦截器中添加了标题跳过功能,但我不知道向哪个请求添加
HttpErrorInterceptorSkip',
。你能再检查一下StackBlitz这个问题吗?如果其他一切都正常的话@不,http客户端没有
-1
状态代码。状态代码
0
表示web浏览器无法完成请求,无法知道是否是连接问题、wifi问题等。。出于安全原因。