如何从Observable检索数据并在拦截器中使用它?

时间:2019-10-08 13:24:30

标签: javascript angular typescript rxjs

我正在Angular 8中构建应用程序的前端。此应用程序使用OAuth 2实现来管理身份验证(密码授予),因此任何HTTP请求(令牌端点的请求除外)都需要在其标头上具有有效的access_token。

要提供上述令牌,我做了一个Angular interceptor,可以从另一个服务中检索令牌,然后将其附加到截获的HTTP请求中。令牌检索方法不会直接提供令牌,而是会提供可观察的结果,最终将其解析为有效的令牌,因此我做出了此选择,因为访问令牌可能无法立即使用,如果令牌已过期,则应用程序需要使用{ {1}}调用,然后刷新的令牌可以传递到HTTP拦截器。

我遇到的问题是,尽管我做了很多尝试,但拦截器并没有等待令牌的检索,因此最终拦截器被跳过,并且HTTP请求没有附加任何令牌。 / p>

这是我的拦截器的代码,HTTPretrieveValidToken,它返回令牌。

Observable

2 个答案:

答案 0 :(得分:2)

可观察对象是异步的。订阅方法之外的代码将不等待其中的代码。

您应返回可观察的结果,而不仅仅是返回其订阅范围内的结果:

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url.includes('localhost:3000') && !req.url.endsWith('token')) {
      return this.facadeService.retrieveValidToken()
        .subscribe(
          res => {
            const clone = req.clone({ setHeaders: { Authorization: `Bearer ${res}` } });
            return next.handle(clone);
          }
        );
    } else {
    return next.handle(req);
    }
  }

类似的东西:

How use async service into angular httpClient interceptor

答案 1 :(得分:0)

问题在于,“拦截”方法应立即返回可观察到的状态,因此,不要订阅“ this.facadeService.retrieveValidToken()”,请使用以下代码:

return this.facadeService.retrieveValidToken().pipe( mergeMap(token => next.handle(req.clone({ setHeaders: { Authorization: 'Bearer ${token}' })) ) )