Angular 2+ HttpIntercept:在返回拦截函数之前等待来自服务器的令牌

时间:2018-05-16 16:13:00

标签: angular rxjs

我知道此问题之前已经以一种方式/形式/形式得到解决,但我已经查看了我能找到的所有问题和答案,但我仍然无法弄清楚如何解决这个问题。

HttpIntercept.intercept必须返回next.handle(request)。但是,我需要它等待(我知道"等待"前端是脏话),以便承载令牌在返回之前从服务器返回。我无法为我的生活找到一种能够实现这一目标的模式。在我们前往服务器获取承载令牌之前,拦截功能无法返回。

如果已经回答,我道歉,请提供相应答案的链接。

非工作示例(函数在附加标记之前返回):

export class TokenInterceptor implements HttpInterceptor {
  constructor(private auth: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    this.auth.getToken().subscribe(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    });

    return next.handle(request);
  }
}

4 个答案:

答案 0 :(得分:2)

使用Observable从其他Observable返回export class TokenInterceptor implements HttpInterceptor { constructor(private auth: AuthenticationService) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { let token: string; return this.auth.getToken().switchMap(response => { token = response['access_token']; request = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); return next.handle(request); }); } }

googlesamples-assistant-devicetool --project-id zzz register-device --device Smart --model Smart  --client-type SERVICE

答案 1 :(得分:2)

我可以想到:

export class TokenInterceptor implements HttpInterceptor {
  constructor(private auth: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.auth.getToken()
        .map(response => request.clone({setHeaders: {Authorization: `Bearer ${response['access_token']}`}}))
        .switchMap(request => next.handle(request));
  }
}

虽然我不确定它会起作用。

答案 2 :(得分:0)

当您的请求是异步时,正在同步调用您的处理程序。

当您需要返回一个observable时,请查看来自rxjs的flatMap / switchMap运算符,它看起来像:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    return this.auth.getToken().flatMap(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
      return next.handle(request);
    });
}

答案 3 :(得分:0)

尝试在Observable完成的函数中返回:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    this.auth.getToken().subscribe(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    },
    err => { console.log(err) },
    () => return next.handle(request) // this is called after the completion of observable
    );

  }
}