在拦截器中收到403后无法重新请求请求

时间:2020-05-18 15:54:34

标签: javascript angular angular-http-interceptors

我打算拦截导致403的请求(因为令牌过期),然后执行请求以获取新令牌,以便能够再次执行失败的请求。

但是由于某种原因,带有新令牌的next.handle(request)没有执行被拦截的请求。

@Injectable()
export class AuthExpiredInterceptor implements HttpInterceptor {
  constructor(
    private accountService: AccountService,
    private readonly authService: AuthService,
    private readonly router: Router
  ) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error) => {
        if (error instanceof HttpErrorResponse && error.status === 403) {
          this._handle403Error(request, next);
        }
        return throwError(error);
      })
    );
  }

  _handle403Error(request: HttpRequest<any>, next: HttpHandler) {
    const refreshToken = localStorage.getItem("refreshToken");
    this.accountService.getNewToken(refreshToken).then(
      (res) => {
        if (res) {
          request = this._addToken(request, this.authService.getToken());
          return next.handle(request); // Don't perform the request intercepted 
        } else {
          this.router.navigate(["/login"]);
        }
      },
      (err) => {
        this.router.navigate(["/login"]);
      }
    );
  }

  _addToken(request: HttpRequest<any>, token: string) {
    return request.clone({
      setHeaders: {
        JWT_TOKEN: token,
      },
    });
  }
}

1 个答案:

答案 0 :(得分:0)

看起来您忘记了返回语句。

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error) => {
        if (error instanceof HttpErrorResponse && error.status === 403) {
          return this._handle403Error(request, next);
        }
        return throwError(error);
      })
    );
  }

_handle403Error(request: HttpRequest<any>, next: HttpHandler) {
    const refreshToken = localStorage.getItem("refreshToken");
    return from(this.accountService.getNewToken(refreshToken)).pipe(
        switchMap(res => {
            if (res) {
                request = this._addToken(request, this.authService.getToken());
                return next.handle(request); // Don't perform the request intercepted 
            }
            return from(this.router.navigate(["/login"])).pipe(switchMapTo(EMPTY));
        }),
        catchError(() => from(this.router.navigate(["/login"])).pipe(switchMapTo(EMPTY)),
    );
}