在RxJS中具有Hot Observable的retryWhen运算符

时间:2019-02-11 09:50:54

标签: angular firebase rxjs firebase-authentication observable

要求是在身份验证令牌过期时获取新值,并保持其最新状态。理想情况下是一个可观察变量(没有单独的主题)

当前代码如下:

constructor(private angularFireAuth: AngularFireAuth) {}

private getAuthTokenResult(): Observable<firebase.auth.IdTokenResult> {
  return this.angularFireAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        return from(user.getIdTokenResult(true));
      } else {
        return of(null);
      }
    })
  );
}

public authToken$: Observable<string> = this.getAuthTokenResult().pipe(
  map((result: firebase.auth.IdTokenResult) => {
    if (new Date() >= new Date(result.expirationTime)) {
      throw new Error('Token Expired');
    } else {
      return result.token;
    }
  }),
  retryWhen(errors =>
    errors.pipe(
      tap(() => console.log('Token Expired. Getting New One...')),
      delay(100),
      take(3)
    )
  ),
  shareReplay(1)
) as ConnectableObservable<string>;

但是,在身份验证令牌过期后,它无法完成工作-无法接收到新令牌。

这就是依赖服务方法的样子

addProduct(
  data: MerchantProductPartial
): Observable<MerchantProduct> {
  return this.authService.authToken$.pipe(
    switchMap(token => {
      // console.log('_addProduct', token);
      if (token) {
        const endpoint = ``;
        const httpOptions = {
          headers: new HttpHeaders({
            'Authorization': `Bearer ${token}`,
          })
        };
        return this.http.post(endpoint, data, httpOptions);
      }
      else {
        throw new Error('Authorization Token not provided.');
      }
    })
  );
}

和方法执行如下

this.merchantService.addProduct({
      name: 'New Test Product'
    }).pipe(take(1)).subscribe(res => console.log('res:', res), err => console.log('err:', err))

解决方案

如果有人担心该解决方案,那就简单了。只需使用其他方法https://firebase.google.com/docs/reference/js/firebase.User#getIdToken即可自动更新无效令牌...只需不强制刷新它即可。

public authToken$: Observable<string> = this.angularFireAuth.authState.pipe(
  switchMap(user: firebase.User => {
    if (user) {
      return from(user.getIdToken());
    } else {
      return of(null);
    }
  })
);

0 个答案:

没有答案