Angular HTTP 拦截器执行内部 http 请求两次

标签 angular interceptor angular-httpclient angular-http-interceptors

我的应用程序使用 JWT token 向后端进行身份验证。我有一个 Angular Interceptor 可以捕获 http 调用中的任何错误。此拦截器检查调用是否返回 401 Unauthorized 响应,如果是,它会调用端点以刷新 token ,然后再次重试原始调用。

我的问题是,出于某种原因,对 refreshToken 端点的调用被执行了两次。

这是我的拦截器(为简洁起见进行了编辑):

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
      catchError((error: any) => {
        switch (error.status) {
          // unauthorized
          case 401:
            // the token is stored in an NGRX store, so retrieve it first
            return this.userStore.pipe(select(fromUser.getUserAccessToken)).pipe(
              take(1),
              mergeMap(userToken => {
                if (userToken) {
                  // token exists but may be invalid, try to refresh
                  return this.userService.refreshToken(userToken).pipe(
                    switchMap(refreshedToken => {
                      if (refreshedToken) {
                        ...
                      } else {
                        // token was not refreshed, delete session
                        ...
                      }
                    })
                  );
                }
              })
            );
        }
      })
    );
  }

return this.userService.refreshToken(userToken) 是执行两次的语句(使用相同的原始 token ),因此第一次调用刷新将通过,第二次调用将通过显然失败了,因为它试图再次刷新相同的 token ,导致用户 session 被删除。

有什么想法吗?

更新: 我还在研究这个。我在我的代码中放置了一堆断点和 console.log:

      catchError((error: any) => {
        >>>>> console.log('1');
        switch (error.status) {
          case 401:
            return this.userStore.pipe(select(fromUser.getUserAccessToken)).pipe(
              take(1),
              mergeMap(userToken => {
                >>>>> console.log('2');
                if (userToken) {
                  return this.userService.refreshToken(userToken).pipe(
                    switchMap(refreshedToken => {
                      >>>>> console.log('3');

Console.log #1 和 #2 只被打印到控制台一次,这意味着 http 错误 只被捕获一次。但是 #3 被打印了两次,我认为这意味着对刷新端点的调用被调用了两次,或者 observable 以某种方式返回了两个值?

最佳答案

不确定为什么,但似乎 refreshToken 输出了多个值。这可以通过 take 运算符轻松解决。像这样:

 return this.userService.refreshToken(userToken).pipe(
                take(1),
                switchMap(refreshedToken => {
                  >>>>> console.log('3');

关于Angular HTTP 拦截器执行内部 http 请求两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64921894/

相关文章:

javascript - Typescript - 将拆分后的字符串推送到数组

JavaScript + MEAN 堆栈 : How to properly find "_id" field (not "id") in array?

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

java - 哪个方面/拦截器处理@Transactional注释

json - 为什么 Angular 4 中的 httpclient 假设请求正在发送 json 数据

angular - 无法从 API 下载 blob 作为 Angular 7 中的文件

angular - Angular Dart-从父路线检索参数

Angular2 服务 : Getting different instances in two components even though there's only one provider

java - 使用 Spring 的类属性更改监听器

c# - CaSTLe Windsor 拦截来自类内部的方法调用