2017-01-16 5 views
4

Angular2アプリケーションでリフレッシュトークンを実装しようとしています。 私は楽観的なアプローチを取っていますが、リクエストを行う前にアクセストークンが期限切れになっているかどうかを調べるのではなく、リクエストを行い、401コードを返す場合は、新しいトークンを要求し、ストレージ。Observableを再試行するときにHTTP上のヘッダーを変更します。

getWithParams<T>(serviceUrl: string, params: URLSearchParams): Observable<T> { 
    return super.getWithParams<T>(serviceUrl, params) 
     .retryWhen((error) => { 
      return error 
       .filter((e) => e.status === 401) 
       .scan((acc, value) => { 
        return acc + 1; 
       }, 0) 
       .takeWhile(acc => acc < 3) 
       .flatMap(() => this.tokenRefreshService.refreshToken()) 
       .delay(1000); 
     }); 
} 

ローカルストレージからそれを取得することで、リクエストヘッダにそのsuper.getWithParams setstheアクセストークンを言及することは重要である:

は、ここに私のコードスニペットです。

メソッド呼び出しtokenRefreshService.refreshToken()は、新しいアクセストークンを取得し、それをローカルストレージに保存します。

私が直面している問題は、要求が再試行されたときに古いアクセストークンを使用している、つまり要求を再構築するためのsuper.getWithParamsを呼び出さないことです。それはただの観察可能なものを再試行するだけです。

リクエストを再度作成する方法はありますか?または失敗したオブザーバブルの要求ヘッダーをchaingする

+0

をこれは、あなたがhttp://stackoverflow.com/questions/39953419/get-new-ticket-then-retry-first-必要なものと非常によく似のように思えますrequest/39955002#39955002、http://stackoverflow.com/questions/39797698/observable-continue-calling-api-and-changing-parameters-based-on-condition。たぶんこれもhttp://stackoverflow.com/questions/41005674/angular-2-http-retrywhen/41014380#41014380 – martin

答えて

3

実際にretryWhen()あなたの利点にそれを使用できるように、ソースに再登録してください。この例では、自分の状況をシミュレートする必要があります。

let token = 'token'; 
let counter = 0; 

const source$ = Rx.Observable.defer(() => { 
    console.log('Observable.defer(), token: ' + token); 
    return Rx.Observable.of(token); 
    }) 
    .map(token => { 
    if (counter++ < 3) { 
     throw new Error('invalid token'); 
    } 
    return token; 
    }) 
    .retryWhen((error) => { 
    return error 
     .filter(() => true) // or whatever... 
     .do(() => token = token + 'bla'); // update the token 
    }) 
    .map(token => { // create the request 
    return "I'm a request with token: " + token; 
    }); 


source$.subscribe(
    res => console.log(res), 
    err => console.log('error: ' + err), 
() => console.log('complete') 
); 

はライブデモを参照してください:https://jsbin.com/roduqi/5/edit?js,console

この3回は、無効なトークンでエラーをスローし、それを毎回更新します。

すべてのエラーで、私は新しいソースObservableをObservable.deferで作成していることに注意してください。

この例では、コンソールに出力します。

Observable.defer(), token: token 
Observable.defer(), token: tokenbla 
Observable.defer(), token: tokenblabla 
Observable.defer(), token: tokenblablabla 
I'm a request with token: tokenblablabla 
complete 
+0

observableでsuper.getWithParamメソッド呼び出しをラップすると、そのトリックが実行されました。ブリリアント! –

関連する問題