要求是在身份验证令牌过期时获取新值,并保持其最新状态。理想情况下是一个可观察变量(没有单独的主题)
当前代码如下:
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);
}
})
);