Вам потребуется создать механизм приостановки всех HTTP-запросов в вашем интерсепторе Angular при возникновении ошибки 401 (неавторизованный доступ). Это можно реализовать с помощью использования RxJS Subject или BehaviorSubject для хранения состояния потока запросов и управления их выполнением до того, как обновление токена завершится.
Вот пример того, как это можно сделать:
```typescript
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError, BehaviorSubject, filter, switchMap, catchError, of } from 'rxjs';
import { AuthService } from './auth.service'; // Сервис для управления аутентификацией
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private isRefreshing = false;
private tokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(private authService: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
return this.handle401Error(request, next);
}
return throwError(() => error);
})
);
}
private handle401Error(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.tokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap((newToken: string) => {
this.isRefreshing = false;
this.tokenSubject.next(newToken);
return next.handle(this.addToken(request, newToken));
}),
catchError(error => {
this.isRefreshing = false;
// Предположим, что мы перенаправляем на страницу входа при ошибке обновления токена
this.authService.logout();
return throwError(() => error);
})
);
} else {
return this.tokenSubject.pipe(
filter(token => token != null),
switchMap(token => {
return next.handle(this.addToken(request, token));
})
);
}
}
private addToken(request: HttpRequest<any>, token: string) {
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
}
```
### Объяснение:
1. **Переменные состояния**:
- `isRefreshing`: Флаг, указывающий, обновляется ли токен в данный момент.
- `tokenSubject`: BehaviorSubject, который хранит новый токен. При его изменении все подписчики будут уведомлены.
2. **Перехват запросов**: В методе `intercept` мы обрабатываем ответ. Если возникает ошибка 401, мы вызываем метод `handle401Error`.
3. **Обработка 401**:
- Если токен еще не обновляется (`!this.isRefreshing`), мы запускаем процесс обновления токена и сохраняем новый токен в `tokenSubject`.
- Если происходит еще один запрос с 401 ошибкой во время обновления токена, подписчики на `tokenSubject` будут ждать, пока токен не будет обновлен.
4. **Добавление нового токена**: Метод `addToken` добавляет новый токен в заголовок запроса.
С помощью такого механизма можно приостановить выполнение новых запросов, пока обновляется токен, и продолжить их выполнение, когда токен будет успешно обновлен.