angular2 – 使用rxjs处理刷新令牌

前端之家收集整理的这篇文章主要介绍了angular2 – 使用rxjs处理刷新令牌前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
因为我已经开始与angular2我已经设置我的服务返回Observable的T.在服务我会有map()调用,使用这些服务的组件只使用subscribe()等待响应。对于这些简单的方案,我did not真的需要挖入到rxjs所以一切OK。

我现在想实现以下:我使用Oauth2身份验证与刷新令牌。我想构建一个api服务,所有其他服务将使用,并将透明地处理刷新令牌时返回401错误。因此,在401的情况下,我首先从OAuth2端点提取新的令牌,然后使用新的令牌重试我的请求。下面是代码工作正常,与promises:

request(url: string,request: RequestOptionsArgs): Promise<Response> {
    var me = this;

    request.headers = request.headers || new Headers();
    var isSecureCall: boolean =  true; //url.toLowerCase().startsWith('https://');
    if (isSecureCall === true) {
        me.authService.setAuthorizationHeader(request.headers);
    }
    request.headers.append('Content-Type','application/json');
    request.headers.append('Accept','application/json');

    return this.http.request(url,request).toPromise()
        .catch(initialError => {
            if (initialError && initialError.status === 401 && isSecureCall === true) {
                // token might be expired,try to refresh token. 
                return me.authService.refreshAuthentication().then((authenticationResult:AuthenticationResult) => {
                    if (authenticationResult.IsAuthenticated == true) {
                        // retry with new token
                        me.authService.setAuthorizationHeader(request.headers);
                        return this.http.request(url,request).toPromise();
                    }
                    return <any>Promise.reject(initialError);
                });
            }
            else {
                return <any>Promise.reject(initialError);
            }
        });
}

在上面的代码中,authService.refreshAuthentication()将获取新令牌并将其存储在localStorage中。 authService.setAuthorizationHeader将“授权”标头设置为以前更新的标记。如果你看看catch方法,你会看到它返回一个promise(对于刷新令牌),在它的轮到最终将返回另一个promise(对于实际的第二次尝试的请求)。

我试图这样做,而不诉诸承诺:

request(url: string,request: RequestOptionsArgs): Observable<Response> {
    var me = this;

    request.headers = request.headers || new Headers();
    var isSecureCall: boolean =  true; //url.toLowerCase().startsWith('https://');
    if (isSecureCall === true) {
        me.authService.setAuthorizationHeader(request.headers);
    }
    request.headers.append('Content-Type',request)
        .catch(initialError => {
            if (initialError && initialError.status === 401 && isSecureCall === true) {
                // token might be expired,try to refresh token
                return me.authService.refreshAuthenticationObservable().map((authenticationResult:AuthenticationResult) => {
                    if (authenticationResult.IsAuthenticated == true) {
                        // retry with new token
                        me.authService.setAuthorizationHeader(request.headers);
                        return this.http.request(url,request);
                    }
                    return Observable.throw(initialError);
                });
            }
            else {
                return Observable.throw(initialError);
            }
        });
}

上面的代码没有做我期望的:在200响应的情况下,它正确地返回响应。然而,如果它捕获401,它将成功检索新令牌,但订阅wil最终检索一个observable而不是响应。我猜这是未执行的Observable,应该做重试。

我意识到,将承诺的工作方式转换到rxjs库可能不是最好的方式去,但我没有能够抓住“一切都是流”的事情。我已经尝试了一些其他解决方案涉及flatmap,retryWhen等…但没有得到远,所以一些帮助是赞赏。

快速查看你的代码,我会说,你的问题似乎是,你不是flattening从刷新服务返回的Observable。

catch操作符期望您将返回一个Observable,它将连接到失败的Observable的结尾,以使下游Observer不知道差异。

在非401情况下,您通过返回一个重新抛出初始错误的Observable来正确地执行此操作。但是在刷新情况下,你返回一个Observable,产生更多的Observable,而不是单个值。

我建议你更改刷新逻辑为:

return me.authService
             .refreshAuthenticationObservable()
             //Use flatMap instead of map
             .flatMap((authenticationResult:AuthenticationResult) => {
                   if (authenticationResult.IsAuthenticated == true) {
                     // retry with new token
                     me.authService.setAuthorizationHeader(request.headers);
                     return this.http.request(url,request);
                   }
                   return Observable.throw(initialError);
    });

flatMap将中间Observables转换为单个流。

原文链接:https://www.f2er.com/angularjs/145175.html

猜你在找的Angularjs相关文章