@laravel_creative_3103

Как приостановить все запросы в Angular при получении ошибки 401, чтобы новые запросы не отправлялись?

Как можно реализовать механизм приостановки всех HTTP-запросов в моем Angular интерсепторе при получении ошибки 401, чтобы избежать их отправки до завершения обновления токена?

export const httpInterceptor: HttpInterceptorFn = (request, next) => {
  let baseUrl = environment.apiUrl;
  let authUrl = environment.authUrl;

  const token = getStorageData<string>('token');
  const router = inject(Router);
  const auth = inject(AuthService);

  let newUrl: string;
  if (request.url.match(/login|logout/) != null) {
    newUrl = `${authUrl}/${request.url}`;
  } else {
    newUrl = `${baseUrl}/api/v1.00/${request.url}`;
  }

  if (token) {
    request = request.clone({
      url: newUrl,
      setHeaders: {
        Authorization: 'Bearer ' + token,
      },
    });
  } else {
    request = request.clone({ url: newUrl });
  }

  return next(request).pipe(
    catchError((error: HttpErrorResponse) => {
      if (
        error.status === 401
      ) {
        if (!auth.isRefreshing()) {
          auth.isRefreshing.set(true);
          auth.refreshTokenSubject.next(null);

          return auth.refreshTokenHandle().pipe(
            switchMap((token: string) => {
              auth.isRefreshing.set(false);
              auth.refreshTokenSubject.next(token);

              return next(
                request.clone({
                  setHeaders: {
                    Authorization: `Bearer ${token}`,
                  },
                })
              );
            }),
            catchError(() => {
              auth.isRefreshing.set(false);
              localStorage.clear();
              router.navigate(['']);

              return throwError(
                () => new Error('Произошла ошибка c обновлением токена.')
              );
            }),
            finalize(() => {
              auth.isRefreshing.set(false);
            })
          );
        } else {
          if (error.error.detail === 'Токен недействителен или просрочен') {
            localStorage.clear();
            router.navigate(['']);
            return throwError(() => error);
          }
          return auth.refreshTokenSubject.pipe(
            filter((token) => token != null),
            take(1),
            switchMap((token) => {
              return next(
                request.clone({
                  setHeaders: {
                    Authorization: `Bearer ${token}`,
                  },
                })
              );
            })
          );
        }
      } else {
        return throwError(() => error);
      }
    })
  );
};
  • Вопрос задан
  • 458 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы