typescript
  • angular
  • rxjs
  • 2016-04-28 105 views 8 likes 
    8

    我是新来Angular2,并试图捕捉401错误与重试原来的请求的计划凭证更新...Angular2:捕获401错误令牌刷新

    这里是我的authService.refresh方法:

    refresh() : Observable<any> { 
        console.log("refreshing token"); 
        this.accessToken = null; 
        let params : string = 'refresh_token=' + this.refreshToken + '&grant_type=refresh_token'; 
        let headers = new Headers(); 
        headers.append('Authorization', 'Basic ' + this.clientCredentials); 
        headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
    
        return Observable.create(
         observer => { 
          this._http.post('http://localhost:8080/oauth/token', params, { 
            headers : headers 
          }) 
          .map(res => res.json()).subscribe(
           (data) => { 
            this.accessToken = data.access_token; 
            observer.next(this.accessToken); 
            observer.complete(); 
           }, 
           (error) => { 
            Observable.throw(error); 
           } 
          ); 
         }); 
    } 
    

    ,然后我尝试在我的组件的方法来使用刷新功能:

    update(index : number) { 
    let headers = new Headers(); 
    headers.append('Authorization', 'Bearer ' + this._authService.accessToken); 
    this._http.get('http://localhost:8080/rest/resource', { 
        headers : headers 
    }) 
    .catch(initialError =>{ 
        if (initialError && initialError.status === 401) { 
         this._authService.refresh().flatMap((data) => { 
         if (this._authService.accessToken != null) { 
          // retry with new token 
          headers = new Headers(); 
          headers.append('Authorization', 'Bearer ' + this._authService.accessToken); 
          return this._http.get('http://localhost:8080/rest/resource', { headers : headers }); 
         } else { 
         return Observable.throw(initialError); 
         } 
         }); 
        } else { 
         return Observable.throw(initialError); 
        } 
    }) 
    .map(res => res.json()) 
    .subscribe(
        data => { 
         this.resources[index] = data; 
        }, 
        error => { 
         console.log("error="+JSON.stringify(error)); 
        } 
    ); 
    } 
    

    这并不是出于某种原因... 我不知道什么是正确的implem令牌刷新功能在angular2中的引入? enter code here

    回答

    2

    没有必要使用Observable.create(

     return this._http.post('http://localhost:8080/oauth/token', params, { 
           headers : headers 
         }) 
         .map(res => res.json()) 
         .map(data => { 
           this.accessToken = data.access_token; 
           observer.next(this.accessToken); 
           observer.complete(); 
          }, 
         ).catch(error) => Observable.throw(error)); 
    

    只是不叫.subscribe()(这将返回Subscription而不是Observable,改用.map(...).catch(...)

    +0

    很抱歉的DV,是我不好,还以为你在谈论的任择议定书的第二部分码。 – paulpdaniels

    +0

    没有问题。感谢您的评论。 –

    4

    除了冈特的回答,我会利用flatMap回调参数中的accessToken而不是使用服务属性:

    if (initialError && initialError.status === 401) { 
        this._authService.refresh().flatMap((accessToken) => { 
        // retry with new token 
        headers = new Headers(); 
        headers.append('Authorization', 'Bearer ' + accessToken); 
        return this._http.get('http://localhost:8080/rest/resource', { 
         headers : headers }); 
        }); 
    } else { 
        return Observable.throw(initialError); 
    } 
    

    这篇文章能吸引你(节“处理安全”):

    +0

    当令牌过期时,多个并发401如何处理? 看来您的解决方案会多次调用refresh(),首先成功,其余的失败。 也许分享其他请求的初始刷新承诺可能会解决此问题。 – user1740331

    相关问题