刷新令牌和访问令牌更改,更改后重复401未经授权的请求Angular 8

时间:2019-12-28 16:00:45

标签: angular

我正在使用拦截器从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,因为我的拦截器不会再次重复失败请求

0 个答案:

没有答案