温馨提示:本文翻译自stackoverflow.com,查看原文请点击:angular7 - angular-7-interceptor-retry-requests-after-token-refresh
angular angular7 angular-http-interceptors

angular7 - 令牌刷新后,Angular-7拦截器重试请求

发布于 2020-03-29 21:47:00

我想在令牌过期的情况下为失败的请求实现拦截器。我尝试了多种方法,但仍然没有成功。

我在下面引用了网址并阅读了多个博客。每个人都建议使用切换图方法,但不能与我合作。 令牌刷新后Angular 4拦截器重试请求

我尝试将所有请求收集到cachedRequests中:Array> = []; 但不知道如何使用它来重新触发失败的请求。

在成功刷新令牌后,this.next.handle(request)无法重新调用。我可以看到更新后的请求对象。

有人可以指出在 Angular 7中用
“ rxjs”:“〜6.3.3”,“ rxjs-compat”:“ ^ 6.5.2”引用的地方来实现拦截器。

以下是对我有用的代码,但仅获得令牌的响应

``````````
    handleError(request: HttpRequest<any>, next: HttpHandler, err) {
            if (err instanceof HttpErrorResponse) {
                if (err.status === 401) {
                    this.service.getNewToken().pipe(filter(token => token != null),
                        take(1),
                        switchMap((token: any) => {
                            console.log('token', token);
                            if (token && token.access_token && token.refresh_token) {
                                sessionStorage.setItem('accessToken', token.access_token);
                                sessionStorage.setItem('refreshToken', token.refresh_token);
                            }
                            request = this.addHeader(request);
                            request.headers.getAll('Authorization');
                            return next.handle(request);
                        })).subscribe(results => this.subject.next(results));

                }
            }
        }

`````````

更新2:尝试多种方法后,我发现

  1. 返回next.handle(request); <-这根本没有被调用
  2. 返回next.handle(request).subscribe(); <-这将被调用,但不会更新对所请求组件的响应。

指针赞赏

查看更多

提问者
nitin1416
被浏览
105
nitin1416 2020-01-31 21:21

回复晚。这就是我的方法。

也可用于并行请求。

import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse, HttpEvent, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { GlobalService } from './global.service';
import { tap, mergeMap, switchMap, filter, take, flatMap, catchError } from 'rxjs/operators';
import { Observable, Subject, throwError, of, BehaviorSubject } from 'rxjs';


@Injectable()
export class InterceptorService implements HttpInterceptor {
    private isRefreshing = false;
    private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
    constructor(public globalService: GlobalService) {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        request = this.addHeader(request);
        // console.log('request ', request);
        return next.handle(request).pipe(catchError((error: any) => {
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401) {
                    if (!this.isRefreshing) {
                        this.isRefreshing = true;
                        this.refreshTokenSubject.next(null);
                        request = this.addHeader(request);
                        console.log('Token request');
                        return this.globalService.getRefershToken().pipe(
                            switchMap((token: any) => {
                                console.log('inside token');
                                this.isRefreshing = false;

                                if (token && token.access_token && token.refresh_token) {
                                    sessionStorage.setItem('accessToken', token.access_token);
                                    sessionStorage.setItem('refreshToken', token.refresh_token);
                                }
                                // request = this.addHeader(request);
                                // console.log('request: ', request);
                                this.refreshTokenSubject.next(token);
                                return next.handle(this.addHeader(request));
                            }));

                    } else {
                        console.log('inside else call');
                        console.log('token : ', this.refreshTokenSubject.getValue());
                        return this.refreshTokenSubject.pipe(
                            filter(token => (token != null && token != undefined)),
                            take(1),
                            switchMap(() => {
                                console.log('adding header in else');
                                return next.handle(this.addHeader(request))

                            }));
                    }
                }
            }
        }));
    }

    private addHeader(request: HttpRequest<any>) {
        let getEndPoint = request.url.split('/')[request.url.split('/').length - 1];
        if (getEndPoint !== 'refreshToken') {
            const accessToken = sessionStorage.getItem('accessToken');
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${accessToken}`
                }
            });
        } else if (getEndPoint === 'refreshToken') {
            const refreshToken = sessionStorage.getItem('refreshToken');
            request = request.clone({
                setHeaders: {
                    applicationCode: environment.applicationCode,
                    'refresh-token': `${refreshToken}`,
                }
            });
        }
        return request;
    }
}