繁体   English   中英

如何从 Observable 中检索数据并在 Interceptor 中使用它?

[英]How to retrieve data from an Observable and use it in an Interceptor?

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

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

我遇到的问题是,尽管我进行了多次尝试,但拦截器并没有等待检索令牌,因此最后会跳过拦截器,并且在没有附加任何令牌的情况下发出HTTP请求。

这是我的拦截器的代码, retrieveValidToken是返回令牌的Observable

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { FacadeService } from './facade.service';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {

  constructor(private facadeService: FacadeService) { }

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

Observables 是异步的。 subscribe 方法外面的代码不会等待里面的代码。

您应该自行返回 observable,而不仅仅是在其订阅中返回结果:

  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);
    }
  }

相似的东西:

如何使用异步服务进入 angular httpClient 拦截器

问题是 'intercept' 方法应该立即返回 observable,所以不要订阅 'this.facadeService.retrieveValidToken()' 使用以下代码:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM