angular - 在 Angular Observable 拦截器中使用 Promise 中的值
问题描述
我正在尝试使用 JWT 拦截器服务来验证用户对 Ionic 4 应用程序 API 的每次调用。我有一个看起来像这样的 JWT 拦截器
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
let token = 'THE_JWT_HERE'
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
return next.handle(request);
}
}
这可以静态地将令牌添加到请求的正确标头中。但是,我需要从基于承诺的 Ionic 存储中获取用户的实际 JWT。
我认为它可能看起来像这样:
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
this.authenticationService.getJWT()
.then(token => {
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
return next.handle(request);
})
}
}
这会在编译时中断,因为我返回的是一个承诺,而不是一个可观察的。但是,如果我放在return next.handle(request)
承诺之外,则不会添加授权标头。我理解为什么会发生这种情况,但我不确定解决方案。
如何从 Promise 中访问该值并在此拦截器中使用它?
解决方案
你想使用一些 rxjs——一种方法可能是 switchMap:
import { switchMap } from "rxjs/operators";
import { from as observableFrom } from "rxjs";
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return observableFrom(this.authenticationService.getJWT())
.pipe(
switchMap(token => {
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
return next.handle(request);
})
);
}
本质上,您希望将该承诺转换为可观察的并将其合并到可观察的链中,从而导致Observable<HttpEvent<any>>
拦截应该返回。
下一个合乎逻辑的问题是,有没有办法缓存 authenticationService 请求,并在请求中简单地使用该缓存值?我建议在服务中使用访问器模式,该模式在第一次请求令牌时查找令牌,然后简单地返回结果。如果您在每个 HttpRequest 之前执行 authenticationService 请求,它会显着减慢您的请求。
推荐阅读
- python - AttributeError:“Lines_LineSeries_LineIterator_DataAccessor_Strateg”对象没有属性“analyers”
- javascript - 我如何为火柴人的腿设置动画并让它看起来像他在同一个地方行走
- reactjs - 如何更新其他组件中数组列表中的项目
- amazon-web-services - route53 会选择最近的区域来处理请求吗?
- ios - 为什么我的@AppStorage 不能在 SwiftUI 上运行?
- python - Linux 命令在控制台中运行良好,但在 .sh 文件中失败?
- javascript - 悬停箭头时滚动 - 像亚马逊网站
- javascript - p5.js 库的所有功能由于某种原因无法正常工作
- batch-file - CMD Line - 帮助为我的文件名添加时间
- php - 我的 HTML 表单无法使用 PHP 邮件程序发送没有附件的电子邮件