角度12 HttpInterceptor等待http客户端方法完成 [英] Angular 12 HttpInterceptor Wait until a http client method finish

查看:0
本文介绍了角度12 HttpInterceptor等待http客户端方法完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在尝试检查令牌何时即将到期,并使用访问令牌重新加载它。 主要问题是,要重新加载它,我必须进行http调用以获取新的令牌,然后将其重新保存在会话存储中。 主要问题是,因为http是异步的,所以它会重新加载令牌,但因为我不知道如何等到此调用完成后才用新令牌重试原始调用,所以它失败了。

代码如下:

AuthService: 这是正在被调用以更新令牌的服务

async reloadIdTokenFromAccess(accessToken : string | null) {
  console.log("Performing call to reload token");
  const resp = await this.httpClient.post<IdTokenDTO>(`${environment.backendUrl}/auth/tokenReload`,accessToken).toPromise();
  this.setIdToken(resp.idToken);
  this.setExpireAt(resp.expireAt);
  console.log("Data update in session storage")
}

拦截器

@Injectable()
export class HttpTokenInterceptor implements HttpInterceptor {

  constructor(private authServ : AuthService) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {

    let token: string | null = this.authServ.getIdToken();
    let expiration: number | null = this.authServ.getExpireAt();
    let reloaded : boolean = false;

    var currentTime = new Date().getTime();

    if(expiration != null && !request.url.includes("tokenReload") && !request.url.includes("login")){
      if(expiration <= currentTime + 60000 && this.authServ.getAccessToken() != null){
        reloaded = true;
        console.log("Token expiration Time near to expire, reloading token")
        this.authServ.reloadIdTokenFromAccess(this.authServ.getAccessToken());
        token = this.authServ.getIdToken();
        console.log("Finish all full reloading")
      }
    }

    if(reloaded){
      console.log("Starting the request with the new token")
    }

    let originalReq = request;

    if(token){
      request = originalReq.clone({
        setHeaders: {
          authorization: `Bearer ${ token }`,
          'Content-Type': 'application/json'
        }
      });
    }

    return next.handle(request);
  }
}
如果我检查日志,我会看到以下内容:

正如您可以检查的那样,在重新加载令牌之前正在执行请求。 如何在继续此方法之前强制完成此请求?

类似于Java中的CompletableFuture,使用get()方法阻止代码,直到代码完成

我也有过这样的测试,但没有成功

async reloadIdTokenFromAccess(accessToken : string | null) {
  console.log("Performing call to reload token");
  await this.httpClient.post<IdTokenDTO>(`${environment.backendUrl}/auth/tokenReload`,accessToken).subscribe( (resp : IdTokenDTO) => {
    this.setIdToken(resp.idToken);
    this.setExpireAt(resp.expireAt);
    console.log("updates token in session storage")
  })
}
import { Injectable } from '@angular/core';
import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor} from '@angular/common/http';
import { from, Observable, Subscription } from 'rxjs';
import { AuthService } from '../services/auth.service';

@Injectable()
export class HttpTokenInterceptor implements HttpInterceptor {

  constructor(private authServ : AuthService) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return from(this.handle(request, next));
  }

  async handle(request: HttpRequest<any>, next: HttpHandler) {

    const expiration: number | null = this.authServ.getExpireAt();
    const currentTime = new Date().getTime();
    let reloaded: boolean = false;

    if (expiration != null && !request.url.includes('tokenReload') &&!request.url.includes('login')) {
      if (expiration <= currentTime + 60000 && this.authServ.getAccessToken() != null) {
        reloaded = true;
        console.log('Token expiration Time near to expire, reloading token');
        await this.authServ.reloadIdTokenFromAccess(this.authServ.getAccessToken());
        console.log('Finish of call reaload token');
      }
    }

    const token = this.authServ.getIdToken();

    if (reloaded){ 
      console.log('Starting the request with the new token');
    }

    const originalReq = request;

    if (token) {
      request = originalReq.clone({
        setHeaders: {
          authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });
    }
    return next.handle(request).toPromise();

  }
}

我穷困潦倒了。不知道该做什么(可能会继续学习课程和教程,但我已经完成了):(

提前谢谢。

推荐答案

authService中,使用Observables返回http响应

reloadIdTokenFromAccess(accessToken : string | null): Observable<IdTokenDTO> {
    console.log("Performing call to reload token");
    return this.httpClient.post<IdTokenDTO>(`${environment.backendUrl}/auth/tokenReload`,accessToken);
}

并且,在您的拦截器中,您将如下操作:

intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    const expiration: number | null = this.authServ.getExpireAt();
    const currentTime = new Date().getTime();
    let reloaded: boolean = false;

    if (
      expiration != null &&
      !request.url.includes('tokenReload') &&
      !request.url.includes('login')
    ) {
      if (
        expiration <= currentTime + 60000 &&
        this.authServ.getAccessToken() != null
      ) {
        reloaded = true;
        console.log('Token expiration Time near to expire, reloading token');

        // unwrap your response from the observable
        this.authServ
          .reloadIdTokenFromAccess(this.authServ.getAccessToken())
          .pipe(
            tap((response: any) => {
              this.authServ.setIdToken(response.idToken);
              this.authServ.setExpireAt(response.expireAt);
              console.log('Data update in session storage');
            })
          )
          .subscribe(() => this.addToken(request, reloaded));
      }
    }

    const req = this.addToken(request, reloaded);
    return next.handle(req);
  }

  private addToken(request: HttpRequest<unknown>, reloaded: boolean) {
    const token = this.authServ.getIdToken();
    console.log('Finish all full reloading');

    if (reloaded) console.log('Starting the request with the new token');

    const originalReq = request;

    if (token) {
      request = originalReq.clone({
        setHeaders: {
          authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });
    }

    return request;
  }

这篇关于角度12 HttpInterceptor等待http客户端方法完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆