在 Angular 可观察拦截器中使用来自 Promise 的值
Using Value from Promise inside Angular Observable Interceptor
我正在尝试使用 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);
}
}
这可以静态地将令牌添加到正确的 header 到请求中。但是,我需要从 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)
置于承诺之外,则不会添加任何授权 header。我明白为什么会这样,但我不确定解决方案。
如何从承诺中访问此值并在此拦截器中使用它?
您想使用一些 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>>
拦截应该 return。
下一个合乎逻辑的问题是,有没有什么方法可以缓存 authenticationService 请求,并在请求中简单地使用缓存的值?我建议在服务中使用一种访问器模式,该模式在第一次请求令牌时查找令牌,然后简单地 returns 结果。如果您在每个 HttpRequest 之前执行 authenticationService 请求,它会显着降低您的请求速度。
我正在尝试使用 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);
}
}
这可以静态地将令牌添加到正确的 header 到请求中。但是,我需要从 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)
置于承诺之外,则不会添加任何授权 header。我明白为什么会这样,但我不确定解决方案。
如何从承诺中访问此值并在此拦截器中使用它?
您想使用一些 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>>
拦截应该 return。
下一个合乎逻辑的问题是,有没有什么方法可以缓存 authenticationService 请求,并在请求中简单地使用缓存的值?我建议在服务中使用一种访问器模式,该模式在第一次请求令牌时查找令牌,然后简单地 returns 结果。如果您在每个 HttpRequest 之前执行 authenticationService 请求,它会显着降低您的请求速度。