Angular12/rxjs7/angularfire异步token拦截器toPromise废弃及报错解决
解决方案
推荐直接改用全RxJS流式处理,彻底规避Promise转换带来的API废弃和类型问题,改写后代码如下:
@Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private auth: AuthService) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const fireUser = this.auth.fireAuthUser.value; if (fireUser) { return this.tokenHandler(request, next, fireUser); } return next.handle(request); } // 移除async标识,直接返回Observable tokenHandler(request: HttpRequest<any>, next: HttpHandler, currentUser: firebase.User): Observable<HttpEvent<any>> { // 将getIdToken的Promise转为Observable,用switchMap切换到请求处理流 return from(currentUser.getIdToken()).pipe( switchMap(authToken => { if (authToken) { request = request.clone({ setHeaders: { Authorization: 'Bearer ' + authToken } }); } return next.handle(request); }) ) } }
修改说明
- 完全移除了
toPromise调用,全程使用RxJS原生操作符处理异步逻辑,解决rxjs 7中toPromise废弃的问题 - 不再经过Promise转换链路,直接返回
Observable<HttpEvent<any>>类型,不会出现undefined返回值,彻底解决类型报错问题 - 流式处理更符合Angular Http拦截器的设计规范,可扩展性更强,后续如果要添加token过期重试、异常处理逻辑都可以直接在pipe中加操作符实现
如果需要保留tokenHandler的async写法,可以用rxjs 7提供的lastValueFrom替代废弃的toPromise,改写如下:
import { lastValueFrom } from 'rxjs'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private auth: AuthService) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const fireUser = this.auth.fireAuthUser.value; if (fireUser) { return from(this.tokenHandler(request, next, fireUser)); } return next.handle(request); } async tokenHandler(request: HttpRequest<any>, next: HttpHandler, currentUser: firebase.User): Promise<HttpEvent<any>> { const authToken = await currentUser.getIdToken(); if (authToken) { request = request.clone({ setHeaders: { Authorization: 'Bearer ' + authToken } }); } // lastValueFrom会等待流完成并返回最后一个发出值,http请求流一定会发出至少一个值,不会返回undefined return lastValueFrom(next.handle(request)); } }
内容的提问来源于stack exchange,提问作者user16831793
相关产品推荐
相关产品推荐

