English 中文(简体)
Angular: 如何在遇到401个错误时提出吉大港山区的请求?
原标题:Angular: How to queue HTTP requests when encountering a 401 error?
  • 时间:2023-04-25 04:33:44
  •  标签:
  • angular
  • rxjs

我有使用JWT信标认证的安热应用。 当吉大港定居人士协会要求退回401个错误(未经批准)时,我需要重新提出象征性的请求并重新研究。

我以前的问题 HTTP Interceptor等到http://www.un.org。

我已安装了一台处理401个错误的吉大港警察局拦截器,指定一个功能,以恢复原状,并重新测试请求。

当只有一个吉大港定居地的申请时,该企业将处以罚款。 然而,我的申请有多种吉大港山区的申请,需要同时执行。 我在路上用叉.,决心一劳永逸地加以执行,但是如果其中一人回去了401个错误,则其他要求将继续下去,也退回了401个。

I d like to implement a solution that queues the requests that fail with a 401 error until the token is refreshed, and then resumes them automatically with the new token. How can I do that?

Previously i have

事先感谢您的帮助。

<>Interceptor>:

export class HttpErrorInterceptor implements HttpInterceptor {
    constructor(
        private _router: Router,
        private _logger: LoggerService,
        private _authService: AuthenticationService
    ) {}

    private isRefreshingToken = false;
    private tokenSubject: BehaviorSubject<string | null> = new BehaviorSubject<
        string | null
    >(null);

    public intercept(
        request: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<IResponse>> {
        return next.handle(request).pipe(
            timeout(appSettings.ajaxTimeout),
            catchError((error) => this.errorHandler(error, request, next))
        );
    }
    
    private errorHandler(
        error: HttpErrorResponse,
        request: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<IResponse>> {
        if (error.error instanceof ErrorEvent) {
            if (!environment.production) {
                /**
                 * !A client-side or network error occurred. Handle it accordingly.
                 * !in development mode printing errors in console
                 */
                this._logger.log( Request error   + error);
            }
        } else {
            const httpErrorCode: number = error[ status ];
            switch (httpErrorCode) {
                case StatusCodes.INTERNAL_SERVER_ERROR:
                    this._router.navigate([ /internal-server-error ]);
                    break;
                case StatusCodes.UNAUTHORIZED:
                    return this.handle401Error(request, next);
                default:
                    this._logger.log( Request error   + error);
                    break;
            }
        }

        return throwError(() => error.error || error);
    }

    
    private handle401Error(
       request: HttpRequest<any>,
       next: HttpHandler
    ): Observable<HttpEvent<any>> {
        if (!this.isRefreshingToken) {
            this.isRefreshingToken = true;
            // Reset here so that the following requests wait until the token
            // comes back from the refreshToken call.
            this.tokenSubject.next(null);
            return this._authService.regenerateTokens().pipe(
                switchMap((apiResult) => {
                    const authData = apiResult.dataset as IAuthResult;
                    this._authService.updateRefreshedTokens(authData);

                    this.tokenSubject.next(authData.tokens.access_token);
                    return next.handle(
                        this.addTokenInHeader(
                            request,
                            authData.tokens.access_token
                        )
                    );
                }),
                catchError((error) => {
                    // If there is an exception calling  refreshToken , bad news so logout.
                    this._authService.logout();
                    this._router.navigate([ / ]);
                    return throwError(() => error);
                }),
                finalize(() => {
                    this.isRefreshingToken = false;
                })
            );
        } else {
            return this.tokenSubject.pipe(
                filter((token) => token !== null),
                take(1),
                switchMap((token) => {
                    return next.handle(this.addTokenInHeader(request, token));
                })
            );
        }
    }

    
    private addTokenInHeader(
        request: HttpRequest<any>,
        token: string | null
    ): HttpRequest<any> {
        return request.clone({
            setHeaders: { Authorization:  Bearer   + token }
        });
    }
}
问题回答

当你遇到<条码>401<<>>>>><>条码>答复时,你愿意停止请求,并在标本重新抬头后继续请求。

One way to accomplish this is to declare your interceptor starting with the current token value, handle the request using that token, then catch 401 responses and initiate a refresh. This assumes you have a service that exposes the current token value as an observable and also a method to initiate a refresh.

export const authInterceptor: HttpInterceptorFn = (request, next) => {
  const authService = inject(AuthService);

  return authService.token$.pipe(
    filter(token => !!token),
    map(token => request.clone({setHeaders: { Authorization: `Bearer ${token}`}})),
    switchMap(authRequest => next(authRequest).pipe(
      catchError(error => {
        if(error.status === 401) {
          authService.refreshToken();
          return EMPTY; 
        }
        return throwError(() => error);
      })
    )),
    takeWhile(event => !(event instanceof HttpResponse), true)
  );
};

有了上述代码,你可以发现,我们不是直接打上next(request),而是建立了一种可观测的平台,从到ken$可观测,过滤到un defined tokens,将有效标语应用到头上,并继续请求。

然后,我们发现反应中的潜在错误,着手进行象征性的复习。 由于<代码>refresh Token() methods on the authservice,token$ to emitun specified,任何其它要求将予以有效撤销,直至收到新标书。

最后,我们使用<条码>,只允许一个<条码>。 HttpResponse response (we do sobre re the request when the token change after HttpResponse has been received.

管道中每个运营商的摘要:

  • filter - pause execution until a non-null token is received
  • map - append the auth header to the request
  • switchMap - handle the request
  • catchError - identify 401 responses and initiate a token refresh; return EMPTY observable
  • throwError - forward unhandled error responses
  • takeWhile - limit to one HttpResponse; use inclusive: true to emit final response.

这里是





相关问题
Angular matSort not working on Date column by desc

Trying to sort the material table with date column , date format is MM/DD/YYYY ,h:mm A , order of date is not by latest date and time. Anything which i missed from the below stackblitz code. https:/...

热门标签