在 Angular 17(函数式 Http 拦截器)中使用 HttpInterceptorFn 重试原始请求

问题描述 投票:0回答:1

当我的拦截器根据 JWT 过期拦截请求时,我遇到了麻烦。我能够执行令牌的刷新,但原始请求永远不会再次重试。

我有以下错误拦截器,除了重试原始请求代码(complete() 内部的部分)之外,它运行良好。 它在完整方法内执行警报和控制台日志,因此执行会一直进行到那里,但永远不会重试原始请求。

export const ErrorInterceptorMethod: HttpInterceptorFn = (
req: HttpRequest<unknown>,
next: HttpHandlerFn,
) => {
const loginService = inject(LoginService);
return next(req).pipe(
  catchError ( error => {

    if (error.status === 401 && req.url !==  environment.urlApiAdmin + '/login') {
      // Unauthorized - JWT Token expired

      console.log("Performing refreshToken request!");

      let reqCloned = req.clone();

      loginService.refreshToken().subscribe({

        error: (errorData) => {
          console.error(errorData);
          console.log("Error refreshing token, logout");
          loginService.logout();
        },

        complete: () => {
          alert("Refresh done, execute again the request!");
          console.log(reqCloned);
          return next(reqCloned); // THIS IS NEVER EXECUTED / DOES NOTHING
        }
      });
    }
    if (error.status === 403) {
      console.log("403 error");
      loginService.logout();
    }
    return throwError(() => error);
  })
)
};

我一直在寻找选项,但找不到任何有用的东西,因为找到的所有示例都使用 HttpHandler 而不是 HttpHandlerFn。

HttpHandlerFn没有.handle方法,所以我找不到有效的方法来实现它。

我还尝试在拦截器之外(在外部服务中)执行此请求,但我无法做到这一点。

有人可以指出我正确的方向吗?

干杯!

angular http jwt request angular-http-interceptors
1个回答
0
投票

伙计们,我已经设法用以下代码解决了这个问题:

      if (error.status === 401 && req.url !==  environment.urlApiAdmin + '/login') {
      // Unauthorized - JWT Token expired
      return loginService.refreshToken().pipe(
        switchMap((tokenReceived) => {
          console.log(tokenReceived);
          sessionStorage.setItem("token", tokenReceived.token);
          loginService.currentAdminToken.next(tokenReceived.token);
          loginService.currentAdminLoginOn.next(true);
          let token : String = tokenReceived.token;
          if (token != '') {
            req = req.clone({
              setHeaders: {
                'Accept' : 'application/json',
                'Authorization' : `Bearer ${token}`,
              },
            })
          }
          return next(req);
        }
        
      ));
    }

问题的关键是调用refreshToken方法,将响应带回管道内 - > switchMap,然后返回原始请求并更改其令牌。

希望这也能帮到你。

干杯

© www.soinside.com 2019 - 2024. All rights reserved.