我正在尝试使用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);
})
}
}
这在编译时中断了,因为我正在返回一个promise,而不是可观察的。
但是,如果我将return next.handle(request)
放在诺言之外,则不会添加任何授权标头。我知道为什么会这样,但是我不确定解决方案。
我怎样才能从Promise中访问此值并在此拦截器中使用它?
答案 0 :(得分:1)
您想使用一些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>>
拦截应该返回。
下一个逻辑问题是,您是否可以缓存身份验证服务请求,而仅在请求中使用该缓存的值?我建议在服务中使用访问器模式,该模式将在第一次请求令牌时查找令牌,然后在此之后简单返回结果。如果您在每个HttpRequest之前都执行了authenticationService请求,则会大大降低请求的速度。