簡體   English   中英

防止在Angular 2中多次調用Access Token API

[英]Prevent multiple calls to Access Token API in Angular 2

我正在Angular 2中開發一個應用程序,其中在不同時間段進行了多個API調用。

當訪問令牌已過期並且需要刷新時,就會出現問題。

對於每個API調用,我都會檢查令牌狀態。

當令牌到期時,將調用訪問令牌API,之后將執行實際的API調用。

只有一個API調用時,此功能可以正常使用。

但是,當令牌到期時有N個API調用時,訪問令牌API也將被調用N次。

這是當前的過程,

postRequest(url, body, header): Observable<Object> {
    //Computation of Access token status
    if (needToken) {
        //Token header and body construction
        return this.http.post(token_url, token_body, token_header).map(
            (res: Response) => {
                //Token Success
            }
        )
        .flatMap(
                success =>
                    this.http.post(url, body, header)  //Actual API
        )
        .map((res: Response) => {
            //Actual API Success
        }
    }
    else {
        return this.http.post(url, body, header).map(
            (res: Response) => {
                //API Success
            }
        )
    }
}

如果令牌到期時有多個API調用,則將執行Token標頭和主體構造過程,甚至在Token API響應之前,其他API也會調用令牌API。

Angular防止異步請求刷新多個令牌

我嘗試使用上面的答案,但是由於我們的函數返回Observable,因此它指出Promise無法分配給Observable。

我遇到了許多使API請求排隊的示例,但是都沒有產生期望的結果。

當對令牌API的調用尚未響應然后如何繼續使用排隊API時,如何使調用API排隊?

在這種情況下,當已經存在對Access令牌API的調用並返回時,正在等待的API應該轉到else部分。

請幫助我。 謝謝。

根據您的需求-這是帶有令牌管理上下文的HttpInterceptor實現的摘要:請注意,為了更好地分離關注點,我使用了:

一種通用的authService,它負責令牌管理(從服務器詢問,保存在緩存中等)。

行動經理-負責決定下一步行動。

import { Injectable } from '@angular/core';

import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor , HttpResponse , HttpErrorResponse} from '@angular/common/http';
import {Observable} from "rxjs";
import {tap} from "rxjs/operators";

import {HttpHandlerService} from "../../http-handler.service";
import {ActionsService} from "../../../actions/actions.service";
import {AuthService} from "../../../../core/auth/auth.service";


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

  constructor(
    private _actionsManager : ActionsService,
    private _authService    : AuthService
  ) {}

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

    //Part 1 - adding headers - only for relevant apis
    var accessToken = this._authService.getToken();
    let authorizationHeader = accessToken ?
    {'Authorization' : 'Bearer ' + accessToken                       , 'content-type' : 'application/json'}:
    {'Authorization' : 'Basic '  + this._authService.getBasicToken() , 'content-type' : 'application/x-www-form-urlencoded'};

    request = request.clone({
      setHeaders: authorizationHeader
    });

    //Part 2 - handling request and responses
    return next.handle(request).pipe(
      tap(
        (event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            // do stuff with response if you want
          }
        },
        (err: any) => {
          if (err instanceof HttpErrorResponse) {
            if (err.status === 401 || err.status === 403) {
                               this._actionsManager.onEvent("unAuthorizedResponseFromServer");
            }
          }
        }
      )
    );
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM