【发布时间】:2017-04-10 21:05:13
【问题描述】:
我在前端使用带有 TypeScript 的 Angular 2。我正在尝试实现一个 http 拦截器,它在每个请求上设置授权标头。如果访问令牌过期,我正在尝试重试请求,使用刷新令牌获取新的访问令牌并在重试之前更改当前请求的标头。
如何在retryWhen操作符中更新请求头?
例如这里是HttpInterceptor:
export class HttpInterceptor extends Http {
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return super.get(url, this.setRequestAuthorizationHeader(options)).retryWhen((errors: any) => this.errorHandler(errors));
}
private setRequestAuthorizationHeader(options?: RequestOptionsArgs): RequestOptionsArgs {
// some checks
// get accessToken from localStorage
options.headers.append('Authorization', 'Bearer ' + accessToken);
}
private errorHandler(errors) {
return errors.switchMap((err) => {
if (err.status === 401) {
let closedSubject = new Subject();
this.authenticationService.refreshToken()
.subscribe(data => {
// How to update authorization header? This doesn't work.
this.defaultOptions.headers.append('Authorization', 'Bearer ' + data.accessToken);
closedSubject.next();
});
return <any>closedSubject;
}
else {
return Observable.throw(err.json());
}
});
}
}
【问题讨论】:
-
当心使用外部服务刷新令牌(我猜
authenticationService也使用Http),你最终会循环依赖HttpInterceptor需要authenticationService需要HttpInterceptor。 -
谢谢,n00dl3。我正在使用注入器动态加载 authenticationService 中的 Http。
-
可以添加认证服务码吗?
-
我会使用
catch而不是retryWhen,后面的会重播相同的Observable... -
如果你有 4 个并行请求,并且它们都有过期的令牌,那么它们都会运行 refreshToken()。正确的?这非常令人困惑,因为 4 个请求将使用相同的令牌生成 4 个 refreshToken。 1 将返回正确的令牌,其他 3 个请求将失败。正确的?我错了吗?解决办法是什么?
标签: angular typescript rxjs observable