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转换为单个流。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 《AngularJS》----$apply 与 $watch
- angularjs – 在离子应用程序中过滤记录
- 如何将字符串写入Scala Process?
- opencv:将Scalar转换为float或double类型
- angularjs – 如何设置ngClick仅用于ngRepeat中的$first元素
- Vim 爱好者看过来,12 个实用的 Vim 使用技巧
- angular – 使用Observable或Observable发出`null`值?
- ofbiz的webservice接口提供(3)-不规范的wsdl的客户端访问
- 如何在AngularJS中为blob发出POST请求
- axis2生成webservice客户端代码及使用方法