在Access令牌到期时,让其他API等待新的Access令牌被提取

时间:2018-08-03 06:20:26

标签: angular api typescript http

我的要求是实现其中的Http post方法函数,

  • 如果有API调用,则只需执行它即可。
  • 但是,如果访问令牌已过期并且存在API调用,则应首先调用访问令牌API。直到它响应并获取新令牌之前,实际的API应该等待。

访问令牌过期时调用的API数量将有所不同。因此,应将任意数量的API排队。

注意: 访问令牌在客户端验证中被声明为“过期”。实际访问令牌的到期时间将在服务器上设置。

如何实现?一个简单的例子将不胜感激。预先谢谢你。

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

请找到示例实现

 intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.sharedAPIProvider = this.inj.get(SharedAPIProvider);


    this.assetupdateArry = { users : 'getUserById' };
    return new Observable<HttpEvent<any>>((subscriber) => {

      // first try for the request
      next.handle(req)
        .timeout(API_TIMEOUT)
        .subscribe(
        (event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            // console.log('success from interceptr');
                  subscriber.next(event);
            subscriber.complete();
          }
        },
        (error) => {
          if (error instanceof HttpErrorResponse) {

            const requestUrl = this.checkUrl(error, sessionAvoidUrls); 
            if (requestUrl && error.status === 401) {
              console.log('401 error, trying to re-login');

              // If more then 10 retry cancel request
              if (this.loginApiRetry > RE_AUTH_COUNT) {
                this.loginApiRetry = 0;
                subscriber.error(error);
              } else {
                this.loginApiRetry = this.loginApiRetry + 1;
                this.resetLoginAPICount();
                // console.log(this.loginApiRetry);
                // try to re-log the user
                this.sharedAPIProvider.reLogin().then((loginResp: any) => {
                  // re-login successful -> create new headers with the new auth token
                  if (loginResp !== undefined) {
                    this.events.publish('loginuser:update', loginResp);
                    const authToken = loginResp.response.authToken;
                    const newRequest = req.clone({
                      headers: req.headers.set('Authorization', authToken),
                    });
                    this.storageProvider.set('authToken', authToken);

                    // retry the request with the new token
                    next.handle(newRequest)
                      .timeout(API_TIMEOUT)
                      .subscribe(
                      (newEvent) => {
                        if (newEvent instanceof HttpResponse) {
                          // the second try went well and we have valid response
                          // give response to user and complete the subscription
                          subscriber.next(newEvent);
                          subscriber.complete();
                        }
                      },
                      (newError) => {
                        // second try went wrong -> throw error to subscriber
                        subscriber.error(newError);
                      });
                  } else {
                    this.events.publish('user:relogin');
                  }
                });
              }
            }  else {
              subscriber.error(error);
            }
          } else {
            // the error was not related to auth token -> throw error to subscriber
            subscriber.error(error);
          }
        });
    });
  }