【发布时间】:2018-06-21 18:49:55
【问题描述】:
我正在开发一个 Ionic 应用程序,并尝试在用户收到 HTTP 请求的 401 响应时兑现刷新令牌。我在网上找到了一些示例,并且能够让这个 (https://www.intertech.com/Blog/angular-4-tutorial-handling-refresh-token-with-new-httpinterceptor/) 工作,但同时出现多个请求。
我遇到的问题是这一系列调用中的第一个调用调用刷新令牌并成功重试,而其他调用从未重试。如果我为已经在进行刷新的请求使用 .filter 和 .take off 主题返回,则调用确实会重试,但没有新令牌。在可观察对象和主题方面,我还很陌生,所以我不太确定问题可能是什么。
请求
this.myService.getData().subscribe(response => {this.data = response.data;});
this.myService.getMoreData().subscribe(response => {this.moreData = response.data;});
this.myService.getEvenMoreData().subscribe(response => {this.evenMoreData = response.data;});
拦截器
@Injectable()
export class HttpInterceptor implements HttpInterceptor {
isRefreshingToken: boolean = false;
tokenSubject = new BehaviorSubject<string>(null);
tokenService: tokenService;
constructor(private authService: AuthService, private injector: Injector) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
return this.authService.getUser().flatMap(user => {
request = this.addToken(request, next, user.accessToken);
return next
.handle(request)
.catch(error => {
if (error instanceof HttpErrorResponse) {
switch ((<HttpErrorResponse>error).status) {
case 401:
return this.handle401(request, next, user);
}
} else {
return Observable.throw(error);
};
})
});
}
addToken(request: HttpRequest<any>, next: HttpHandler, accessToken: string): HttpRequest<any> {
return request.clone({ setHeaders: { Authorization: 'Bearer ' + accessToken }})
}
handle401(request: HttpRequest<any>, next: HttpHandler, user: any) {
if (!this.isRefreshingToken) {
this.isRefreshingToken = true;
this.tokenSubject.next(null);
this.tokenService = this.injector.get(tokenService);
return this.tokenService.refresh(user.refreshToken)
.switchMap(refreshResponse => {
if (refreshResponse) {
this.authService.setUser(refreshResponse.id_token, refreshResponse.access_token, refreshResponse.refresh_token);
this.tokenSubject.next(refreshResponse.accessToken);
return next.handle(this.addToken(request, next, refreshResponse.access_token));
}
else {
//no token came back. probably should just log user out.
}
})
.finally(() => {
this.isRefreshingToken = false;
});
}
else {
return this.tokenSubject
.filter(token => token != null)
.take(1)
.switchMap(token => {
return next.handle(this.addToken(request, next, token));
});
}
}
}
【问题讨论】:
标签: javascript angular rxjs