我正在使用拦截器从catchErrors中检测401错误
这是我的拦截器 我正在使用ngrx存储获取刷新令牌,因此请求执行得很好,但是再也没有调用失败请求,我发现stackoverflow中的所有问题都对我不起作用
@Injectable()
export class InterceptService implements HttpInterceptor {
connected: boolean = false;
subject: Subject<any> = new Subject();
// for Refresh Token
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(
private toastService: ToastService,
private translate: TranslateService,
private _store: Store<AppState>,
private userLocalStorage: UserLocalStorageService,
private route: Router
) {
}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let token: string = this.userLocalStorage.getToken();
if (token) {
request = request.clone({
headers: request.headers.set('Authorization', 'Bearer ' + token)
});
}
if (!token) {
request = request.clone({
headers: request.headers.set('Accept-Language', localStorage.getItem('language'))
});
}
if (request.url.includes('Upload')) {
} else {
if (!request.headers.has('Content-Type')) {
request = request.clone({
headers: request.headers.set('Content-Type', 'application/json')
});
}
request = request.clone({
headers: request.headers.set('Accept', 'application/json')
});
}
return next.handle(request).pipe(
tap((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
if (event.status === StatusCodes.SUCCESS) {
}
}
return event;
}),
catchError((errors: HttpErrorResponse) => {
if (errors.status === StatusCodes.BADREQUEST) {
if ('validationErrors' in errors.error && errors.error.message === 'Validation errors')
this.toastService.showToast('top-end', '200px', errors.error.validationErrors[0], 'error');
else
this.toastService.showToast('top-end', '200px', errors.error.message, 'error');
}
if (errors.status === StatusCodes.NOTFOUND) {
this.toastService.showToast('top-end', '200px', this.translate.instant('TRANSLATOR.THEREISANERROR'), 'error');
}
if (errors.status === StatusCodes.UNAUTHORIZED) {
// calling refresh token api and if got success extracting token from response and calling failed api due to 401
if (errors.headers.has(ConstantsStrings.TokenExpired)) {
console.log('error');
console.log(this.isRefreshing);
this.handle401Error(request, next);
} else {
this.toastService.showToast('top-end', '200px', this.translate.instant('TRANSLATOR.YOUDONTHAVEPERMISSIONTODOTHIS'), 'error');
this.route.navigateByUrl(`${RouteStrings.error}${StatusCodes.UNAUTHORIZED}`);
}
}
if (errors.status === StatusCodes.FORBIDDEN) {
this.toastService.showToast('top-end', '200px', this.translate.instant('TRANSLATOR.YOUDONTHAVEPERMISSIONTODOTHIS'), 'error');
this.route.navigateByUrl(`${RouteStrings.error}${StatusCodes.UNAUTHORIZED}`);
}
return throwError(errors);
}),
retryWhen((errors) => errors.pipe(
flatMap((error, index) => {
console.log(error);
console.log(request);
if (!error.status || error.status !== 401) {
return throwError(error);
}
if (index === 0) {
this.userLocalStorage.addToken(request, this.userLocalStorage.getToken())
} else {
}
return of(error).pipe(delay(7500));
}),
take(2)
)),
);
}
private handle401Error(req: HttpRequest<any>, next: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
const data = new RefreshTokenModel();
data.accessToken = this.userLocalStorage.getToken();
data.refreshToken = this.userLocalStorage.getRefreshToken();
this._store.dispatch(new RefreshTokenRequested({ refreshTokenData: data }));
this._store.select(getRefreshToken).pipe(skipWhile(a => a.accessToken === undefined
&& a.refreshToken === undefined), switchMap(tokens => {
this.refreshTokenSubject.next(tokens.accessToken);
this.userLocalStorage.removeAccessTokenAndRefreshToken();
this.userLocalStorage.setAccessTokenAndRefreshToken(tokens.accessToken, tokens.refreshToken);
window.location.href = this.route.url;
return next.handle(this.userLocalStorage.addToken(req, tokens.accessToken));
}),
catchError(error => {
console.log(error);
return throwError(error);
})
, finalize(() => {
this.isRefreshing = false;
})).subscribe();
}
}
}
我的代码返回的是未定义的,但是我添加了return之后,它可以正常工作,但是我导航到基本URL,因为我的拦截器不会再次重复失败请求