4

angular 2アプリでは、APIへのすべてのリクエストにトークン付きのヘッダーがあり、トークンの有効期限が切れた場合、APIは401 httpコードで応答します。トークンを更新する方法はありますが、新しいトークンの取得中に他の人を一時停止して前のリクエストを再送信するにはどうすればよいですか?

4

1 に答える 1

2

Httpこの方法でクラスを拡張し、catchオブザーバブルの演算子を使用してエラーをキャッチできます。

アプローチとして、HTTP オブジェクトを拡張してエラーをインターセプトすることが考えられます。

@Injectable()
export class CustomHttp extends Http {
  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
    super(backend, defaultOptions);
  }

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    console.log('request...');
    return super.request(url, options).catch(res => {
      // do something
    });        
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    console.log('get...');
    return super.get(url, options).catch(res => {
      // do something
    });
  }
}

以下のように登録します。

bootstrap(AppComponent, [HTTP_PROVIDERS,
    new Provider(Http, {
      useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
      deps: [XHRBackend, RequestOptions]
  })
]);

オペレーターで定義されたコールバック内で、catchメソッドを呼び出してトークンを更新し、結果を取得し、ソース リクエストに新しいトークンを設定して、再度実行することができます。これは完全に透明になります。

以下にサンプルを示します。

get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.get(url, options).catch(res => {
      if (res.status === 401) {
        return this.getToken().flatMap(token => {
          var sourceOptions = options || {};
          var headers = sourceOptions.headers || new Headers();
          headers.append('Authorization', token); // for example
          return super.get(url, options);
        });
      }

      return Observable.throw(res);
    });
  }

編集

他のリクエストを「一時停止」するには、 and演算子getTokenを使用してメソッド内にキャッシングを実装する必要があります。doshare

getToken() {
  if (hasTokenExpired()) {
    this.token = null;
    this.tokenObservable = null;
  }

  if (this.token) {
    // Gotten the new token
    return Observable.of(this.token);
  } else if (this.tokenObservable) {
    // Request in progress...
    return this.tokenObservable;
  } else {
    // Execute the "refresh token" request
    return this.get('/refreshToken')
      .map(res => res.json)
      .do(token => {
        this.token = token;
        this.tokenObservable = null;
      })
      .share();
  }
}
于 2016-05-18T18:36:24.587 に答える