SAP UI5 應用讀取 CSRF token 的 HTTP head 請求邏輯解析

注销發表於2022-02-16

SAP UI5 應用在傳送 OData batch 請求之前,會透過下列的_createBatchRequest方法構造 batch 請求物件:

var oBatchRequest = that._createBatchRequest(aReadRequests);

該請求物件的 data 欄位裡,包含 batch 具體的 payload:

  • Invoices?$skip=0&$top=100&$orderby=ShipperName%20asc
  • Invoices/$count

該請求頭部欄位 Accept 為 multipart/mixed:

然後透過 oWrappedBatchRequestHandle.oRequestHandle = that._submitBatchRequest(oBatchRequest, aBatchGroup, fnSuccess, fnError) 方法進行提交。

token handling 標誌位為 true,且方法不為 POST,因此在執行 batch 操作之前,先要獲取 CSRF token:

進入函式refreshSecurityToken.

構造發起 token 請求的 request 物件:

url 為:https://services.odata.org/V2...

首先嚐試 head 請求,如果報錯,再切換成 get 請求:

// Initially try method "HEAD", error handler falls back to "GET" unless the flag forbids HEAD request
        if (this.bDisableHeadRequestForToken) {
            mTokenRequest.request = requestToken("GET", handleGetError);
        } else {
            mTokenRequest.request = requestToken("HEAD", handleHeadError);
        }

請求 token 的 HTTP 請求的 Content-type 設定邏輯,和標誌位 bJson 有關:

request 物件:

最重要的頭部欄位 x-csrf-token, 值被填充成 fetch:

function requestToken(sRequestType, fnError) {
            // trigger a read to the service url to fetch the token
            oRequest = that._createRequest(sUrl, "", sRequestType,
                that._getHeaders(undefined, true), null, null, !!bAsync);
            oRequest.headers["x-csrf-token"] = "Fetch";
            return that._request(oRequest, handleSuccess, fnError, undefined, undefined, that.getServiceMetadata());
        }

執行了 head 請求後,響應的狀態碼是 200,但是 responseText 欄位值是空的。

還是進入 success callback:

使用 handler 讀取 token 請求的 response,這個 handler 支援的 content-type 型別:application/atomsvc+xml;q=0.8, application/json;odata=fullmetadata;q=0.7, application/json;q=0.5, /;q=0.1

這裡因為 response.body 是空的,因此進入不了 dispatchHandler的處理邏輯:

然後進入 refreshToken 的 callback:

當然是拿不到 token 的:

進入 else 分支:

清除所有相關的 token 標誌位:

ODataModel.prototype.resetSecurityToken = function() {
        delete this.oSharedServiceData.securityToken;
        delete this.oHeaders["x-csrf-token"];
        delete this.pSecurityToken;
    };

resolve 一個空的 token 給 callback:

這個 head 請求的響應碼為 200,但是響應頭部沒有附帶 csrf token:

更多Jerry的原創文章,盡在:"汪子熙":

相關文章