Я использую angular universal в своем проекте, а для своей аутентификации я использую токен доступа с продолжительностью 15 минут и токен refre sh с продолжительностью 24 часа. когда я получаю приложение с сервера, я разрешаю пользователя из api, а затем загружаю (accesToken и refreshToken - это файлы cookie, которые получает сервер). Теперь я хочу, чтобы сервер перешел на страницу входа в систему, если токен refre sh недействителен или истек. Я обрабатываю все эти ошибки в своем перехватчике. Если я получаю 401, я использую токен refre sh, чтобы получить новый токен доступа и повторно отправить исходный запрос, но если запрос токена refre sh завершится неудачно, я хочу вывести пользователя из системы. код перехватчика:
const InterceptorSkipHeader = 'X-Skip-Interceptor';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private refreshTokenInProgress = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(
private cookies: CookiesService,
private sb: AppSandbox, private apiService: ApiService, private authService: AuthService, private router: Router) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.headers.has(InterceptorSkipHeader)) {
const headers = req.headers.delete(InterceptorSkipHeader);
return next.handle(req.clone({ headers }));
}
const token = this.authService.accessToken;
return next.handle(
token !== null
? req.clone({ setHeaders: { 'authorization': `Bearer ${token}` } })
: req
).pipe(catchError((err) => {
if (err instanceof HttpErrorResponse) {
if (err.status !== 401) {
return throwError(err);
}
if (this.refreshTokenInProgress) {
return this.refreshTokenSubject.pipe(filter(result => result != null), take(1), switchMap((result) => {
return next.handle(req.clone({ setHeaders: { 'authorization': `Bearer ${result}` } }));
}));
} else {
this.refreshTokenInProgress = true;
this.refreshTokenSubject.next(null);
const refreshToken = this.authService.refreshToken;
return this.apiService.sendRequest(EHttpMethod.GET, EApiEndpoints.REFRESH_AUTH_TOKEN,
null, null, new HttpHeaders()
.set('X-Skip-Interceptor', 'true').set('authorization', `Bearer ${refreshToken}`)).pipe(
switchMap((res) => {
this.authService.setNewAccessToken(res.accessToken);
this.refreshTokenInProgress = false;
this.refreshTokenSubject.next(res.accessToken);
return next.handle(res.accessToken !== null
? req.clone({ setHeaders: { 'authorization': `Bearer ${res.accessToken}` } })
: req);
}), catchError((error) => {
this.refreshTokenInProgress = false;
this.sb.userLogout();
return throwError(error);
})
);
}
}
}));
}
}
последняя ошибка catchError должна обрабатывать именно этот случай, но почему-то я получаю только ошибку на сервере, и никакой навигации не происходит (приложение зависает).