【问题标题】:Using Value from Promise inside Angular Observable Interceptor在 Angular Observable 拦截器中使用 Promise 中的值
【发布时间】:2019-02-19 22:33:24
【问题描述】:

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

【问题讨论】:

    标签: angular promise observable angular7 ionic4


    【解决方案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&lt;HttpEvent&lt;any&gt;&gt;

    下一个合乎逻辑的问题是,有没有办法缓存 authenticationService 请求,并在请求中简单地使用该缓存值?我建议在服务中使用访问器模式,该模式在第一次请求令牌时查找令牌,然后简单地返回结果。如果您在每个 HttpRequest 之前执行 authenticationService 请求,它会显着减慢您的请求。

    【讨论】:

    • 感谢您的回答遗弃。我相信您要求的模式正是我正在寻找的。我现在收到一个错误,即属性 switchMap 存在于 Observable> 类型上。知道如何解决吗?至于第二个问题,getJWT() 方法从离子存储中检索 JWT。离子存储库是基于承诺的,因此是我的问题。
    • 我必须在 switchMap 之前使用 .pipe,并且令牌正在评估为一个承诺。
    • 对不起,我想你想要 import { from as observableFrom } 为在我头顶输入未经检查的代码而道歉。将您需要的承诺转换为“来自”而不是“来自”——编辑答案以反映这些变化
    • 做到了!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    相关资源
    最近更新 更多