typescript
  • angular
  • rxjs
  • 2016-04-28 106 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

    相關問題