在角度可观察拦截器中使用Promise中的值

时间:2019-02-19 22:33:24

标签: angular promise observable angular7 ionic4

我正在尝试使用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中访问此值并在此拦截器中使用它?

1 个答案:

答案 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请求,则会大大降低请求的速度。