如何将Firebase JWT添加到Angular的HTTP请求中?
问题解决方法
你当前的写法存在一个问题:将delete方法声明为async后,实际返回值是Promise<Observable<T>>而非直接的Observable<T>,调用方需要先await拿到Observable实例才能订阅,不符合Angular HttpClient的常规使用习惯。
方案1:修改现有方法,适配Observable流程
可以用RxJS的from方法将返回Promise的token获取逻辑转成Observable,再通过switchMap拼接后续的HTTP请求流,修改后代码如下:
import { from, Observable, switchMap } from 'rxjs'; delete<T = any>(appendix: string): Observable<T> { // 将Promise转为Observable return from(this.httpOptions()).pipe( // 拿到请求配置后切换到HTTP请求流 switchMap(options => this.http.delete<T>(this.url + appendix, options)) ); } // 原有httpOptions方法无需修改 private async httpOptions(): Promise<{ headers: { uid: string } }> { const user: User = this.authQuery.getValue(); // 建议补充用户不存在、token获取失败的错误处理逻辑 const token: string = await user.getIdToken(); return { headers: {uid: token}, }; }
GET、POST、PUT等其他封装的方法都可以按照相同逻辑修改。
方案2(更推荐):全局Http拦截器统一添加请求头
如果所有业务请求都需要携带该JWT头,直接使用Angular原生的HttpInterceptor做全局拦截处理,无需在每个封装的请求方法中重复写token获取逻辑:
- 首先新建拦截器文件:
// jwt.interceptor.ts import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http'; import { from, Observable, switchMap } from 'rxjs'; // 替换为你实际的authQuery导入路径 import { authQuery } from './auth/query'; @Injectable() export class JwtInterceptor implements HttpInterceptor { intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const user = authQuery.getValue(); // 无登录用户时直接放行请求 if (!user) { return next.handle(request); } // 拿取token后克隆原请求添加头信息 return from(user.getIdToken()).pipe( switchMap(token => { const reqWithToken = request.clone({ headers: request.headers.set('uid', token) }); return next.handle(reqWithToken); }) ); } }
- 在根模块(一般是AppModule)的providers数组中注册拦截器:
@NgModule({ // ...其他配置 providers: [ { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true } ] }) export class AppModule { }
配置完成后你封装的HTTP服务方法不需要再做任何token相关处理,直接按照原生HttpClient的写法即可:
delete<T = any>(appendix: string): Observable<T> { return this.http.delete<T>(this.url + appendix); }
该方案可大幅减少重复代码,后续调整头信息规则也只需要修改拦截器一处,维护成本更低。
内容的提问来源于stack exchange,提问作者Andreas Rainer
相关产品推荐
相关产品推荐

