1

我正在使用带有访问/刷新令牌的 OAuth。我按照这些示例尝试捕获未经授权的 http 调用,自动刷新令牌,然后使用新令牌重试调用:

使用 rxjs 处理刷新令牌

https://www.illucit.com/blog/2016/03/angular2-http-authentication-interceptor/

http://restlet.com/company/blog/2016/04/18/interacting-efficiently-with-a-restful-service-with-angular2-and-rxjs-part-3/

我正在扩展 Angular 的 Http 类并成功捕获 401。我的问题是当我几乎同时有多个 http 调用时。他们都返回未经授权的 401。然后他们都尝试刷新令牌。第一个成功到达服务器的人获得了新的令牌,并用新的令牌重试了它的 http 调用。但是,所有其他调用都尝试使用相同的刷新令牌执行相同的操作,而无需等待第一个调用返回新令牌。这导致后端出现错误。

理想情况下,第一个返回 401 的 http 调用会经历获取新令牌的过程,而所有其他被拦截的调用会等待第一个调用完成。但是根据我发布的示例,我不知道如何“暂停”后者拦截 401 错误并等待第一次调用返回的令牌。

我正在使用可观察的。

4

1 回答 1

0

您可能可以将当前可观察到的刷新令牌设置为类上的一个变量,并检查它是否不为空,因为您的其他调用返回为 401s。如果它不为空,请等待它完成然后重试。

这是我写的一些非常基本的伪代码。我不是 100% 确定它会起作用。我也确信有更多的 rxjs'y 方式来重试原始请求,而不是this.get(url)再次显式调用

private refreshObservable: Observable<T>;

public get<T>(url: string) : Observable<T> {
    return this.http.get(url)
        .catch(err => {
            //assuming err is a 401..
            return (this.refreshObservable || this.refreshTokens()).flatMap(() => this.get(url));
        })
}

private refreshTokens() {
    return this.refreshObservable = this.http.get('refreshendpoint').do(() => this.refreshObservable = null).share();
}
于 2017-03-22T19:34:30.527 回答