附註:
- 此教學課程需要存取 Oracle Cloud。若要註冊免費帳戶,請參閱開始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 憑證、租用戶及區間的範例值。完成實驗室時,請以雲端環境特有的值取代這些值。
使用 OCI API 閘道、函數及可觀察性來驗證 JSON 內容及監控 API 標頭和主體
簡介
當我們開發分散式應用系統時 (特別是在以微服務為基礎的架構中),我們希望元件在執行時能夠順利調整及執行。它們具有非常複雜的架構、執行其他元件、執行其他元件的元件,以及其他元件在無限數目的無窮呼叫中。
規劃如何發展每一項都是非常重要的任務。您可以透過 Oracle Cloud Infrastructure API Gateway (OCI API Gateway) 顯示建立在 Kubernetes 叢集上的微服務。有一系列設施,例如執行呼叫驗證和授權、資料驗證和呼叫最佳化等,只需幾個名稱即可。現有方法不足以解決需求時,也可以使用 OCI Functions 執行呼叫,以建立個人化認證和授權機制。
本教學課程將說明如何使用自訂機制來驗證部分使用案例,例如:
-
驗證 JSON 參數資料的大小。
-
驗證 JSON 項目數目上限。
儘管這是 OCI API 閘道中認證和授權的機制,但它仍有助於滿足其他需求,例如:
-
從 HEADER、查詢參數或 REST 呼叫的主體擷取資料。
-
將此資料傳送給 OCI Observability,目的是促進問題的除錯,如果沒有此資訊,通常無法偵測。
注意:如果您要將資料傳送至「可觀察性」,請考慮在程式碼中作為最佳做法,使用隱匿 HEADER 或 BODY 內容,例如密碼或機密資料。另一種方法是開啟 / 關閉您的函數,以進行除錯。
目標
-
設定 API 部署。
-
開發 OCI 函數以從 API 要求擷取 HEADER 和 BODY。
-
驗證主體 JSON 資料。
-
將 HEADER 和 BODY 資訊傳送至 OCI 可觀察性。
必要條件
-
運作中的 Oracle Cloud 租用戶。您可以建立每月 300.00 美元的免費 Oracle Cloud 帳戶,以試用此教學課程,請參閱建立免費的 Oracle Cloud 帳戶。
-
OCI API 閘道執行處理在網際網路上建立並公開,請參閱在 Oracle Cloud 中建立您的第一個 API 閘道。
作業 1:設定 OCI 可觀察性
-
在您的 OCI 租用戶中建立日誌,以從您的函數擷取日誌。瀏覽至可觀測性與管理,然後在 OCI 主控台中選取日誌。
-
按一下建立自訂日誌。
-
在自訂日誌名稱欄位中輸入名稱,然後選擇適當的區間和日誌群組。
注意:擷取日誌的 OCID 很重要,您的程式碼需要這麼做。
作業 2:建立 OCI 函數以從 API 要求擷取 HEADER 和 BODY
若要執行下列步驟,請從 function.zip 下載程式碼。
-
從 API 要求擷取 HEADER 和 BODY。
-
驗證主體 JSON 資料,有一個驗證每個陣列項目數的方法。
-
將 HEADER 和 BODY 資訊傳送至 OCI 可觀察性。
import io import json import logging import requests import oci from fdk import response from datetime import timedelta def count_items(dictData): counting = 0 for item in dictData: if type(dictData[item]) == list: counting += len(dictData[item]) else: if not type(dictData[item]) == str: counting += count_items(dictData[item]) return counting def handler(ctx, data: io.BytesIO = None): jsonData = "API Error" c = 0 try: config = oci.config.from_file("./config","DEFAULT") logging = oci.loggingingestion.LoggingClient(config) rdata = json.dumps({ "active": True, "context": { "requestheader": data.getvalue().decode('utf-8'), }, }) jsonData = data.getvalue().decode('utf-8') # Get the body content from the API request body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"] body = dict(json.loads(body)) # Count the number of items on arrays inside the JSON body c = count_items(body) # If JSON body content has more than 1 item in arrays, block the authorization for the API backend if (c > 1): # Send a log to observability with out of limit of items in array put_logs_response = logging.put_logs( log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", put_logs_details=oci.loggingingestion.models.PutLogsDetails( specversion="EXAMPLE-specversion-Value", log_entry_batches=[ oci.loggingingestion.models.LogEntryBatch( entries=[ oci.loggingingestion.models.LogEntry( data="out of limit of items in array " + str(c), id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")], source="EXAMPLE-source-Value", type="EXAMPLE-type-Value")])) return response.Response( ctx, status_code=401, response_data=json.dumps({"active": False, "wwwAuthenticate": "API Gateway JSON"}) ) # Send a log to observability with HEADERs and BODY content put_logs_response = logging.put_logs( log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", put_logs_details=oci.loggingingestion.models.PutLogsDetails( specversion="EXAMPLE-specversion-Value", log_entry_batches=[ oci.loggingingestion.models.LogEntryBatch( entries=[ oci.loggingingestion.models.LogEntry( data=jsonData, id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")], source="EXAMPLE-source-Value", type="EXAMPLE-type-Value")])) return response.Response( ctx, response_data=rdata, status_code=200, headers={"Content-Type": "application/json"} ) except(Exception) as ex: jsonData = 'error parsing json payload: ' + str(ex) + ", " + json.dumps(jsonData) pass return response.Response( ctx, status_code=401, response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData}) )
瞭解程式碼
您可以在 function.zip 找到此程式碼。
注意:如果您不知道如何開發函數並在 API 閘道中呼叫函數,請參閱使用 API 閘道呼叫函數。
-
count_items 方法,用來計算 JSON 結構內任何陣列中的項目。
-
此部分程式碼使用 OCI SDK for Python 載入組態檔和私密金鑰以存取您的 OCI 租用戶。
-
rdata 會從要求擷取參數,並準備回應以授權函數呼叫 API 閘道組態的後端。
active
=True
將會執行授權。 -
jsonData 將用於產生 OCI 可觀察性的 HEADER 和 BODY 內容。
-
此程式碼只會從要求擷取 BODY JSON 結構。
-
以下程式碼將會計算 BODY JSON 結構內陣列上的項目。如果項目計數超過 1 個項目,作用中將設為 False ,錯誤日誌將會傳送至 OCI 可觀察性。若要傳送日誌,您必須使用 Python OCI SDK 。
注意:將 log_id 變數取代為工作 1 中產生的 OCID 日誌。
如果計數小於或等於 1,則會在 OCI 可觀察性中產生要求 HEADER 和 BODY 內容的日誌。請務必將 log_id 變數取代為您的 OCID 日誌。
注意:您可以在不同的 OCI 日誌中產生日誌。在此教學課程中,只建立一個日誌,但是您可以建立其他日誌。
-
如果發生錯誤,會在此處產生含有錯誤的訊息。
設定 OCI 的 SDK 認證
您必須先設定組態檔並將您的 OCI 私密金鑰和指紋與函數放在一起,才能將其部署到 OCI。您必須在 Oracle Cloud Infrastructure Command Line Interface (OCI CLI) 安裝與組態上產生 config 和私密金鑰檔案。
若要安裝並設定您的 OCI CLI,請參閱安裝 OCI CLI 。此安裝與配置將為您產生兩個檔案。尋找 config 和 private key 檔案 (預設為 oci_api_key.pem)。資料夾路徑將在安裝指示中通知。
下載 function.zip 以查看程式碼、組態檔及私密金鑰。以您的 OCI CLI 檔案取代組態檔和私密金鑰檔。
建置及部署 OCI 函數
在此步驟中,我們將需要使用 OCI CLI 來建立 OCI 函數,並將程式碼部署到您的租用戶中。若要建立 OCI 函數,請參閱 OCI Functions QuickStart 並搜尋 Python 選項。您將需要使用此資訊來建立函數:
- 應用程式:fn_apigw_json
請記住您部署函數的區間。您需要此資訊來設定 OCI API 閘道部署。
作業 3:設定 API 閘道中的 OCI 函數
讓我們部署您的 API 並與您的 OCI 函數整合,以驗證要求參數 (標頭和 BODY) 並傳送至 OCI 可觀察性。如果您不知道如何在 OCI API 閘道中顯示後端,請參閱 OCI API 閘道:設定、建立及部署 API 。
-
開啟編輯建置。
-
按一下認證段落。
-
按一下單一認證,然後選取授權器函數。
-
選擇函數區間 (在您部署函數的位置),選取 fn_apigw_json 應用程式和函數 python-json-header 。
-
設定「函數引數」以擷取 HEADER 和 BODY 。擷取名為 header 與 header2 的 HEADER ,以及將命名為 body 的 BODY 內容。
-
按一下路由並設定標頭轉換。此組態是選擇性的,只是查看要求資料 (HEADER 和 BODY 內容) 的回應內容或要求所產生的錯誤。除錯您的函數會很有用。
作業 4:測試您的請求
注意:在您的「API 建置」中,如果您設定「授權者函數」並設定「函數引數」,就會啟用「函數」引數的快取。您可以建立要快取的資料類型。您可以設定查詢參數或標頭的快取,但無法設定主體內容。
我們可以測試 API 要求。進行主體陣列中只有一個項目的測試。
curl --location 'https://xxxxxxxxxxxxxxxxxxxx.apigateway.us-ashburn-1.oci.customer-oci.com/path_index/path' \
--header 'Content-Type: text/plain' \
--header 'header: header' \
--header 'header2: header2' \
--header 'header3: header3' \
--data '{"data": {"clientID": "xxxxxxxxxxxxxxxxxxx", "secretID": "xxxxxxxxxxxxxxxxxxx", "jList":[{"added_by":"Ani","description":"example description.","start_date":"2014-10-10","mark":255,"id":975}]}}' -i
header3 已傳送但顯示在日誌中,因為未在 OCI API 閘道中將其設定為函數引數。BODY JSON 陣列上只有一個項目,因此它是一個有效的授權要求。
讓我們在陣列和測試上再放置一個項目。
curl --location 'https://xxxxxxxxxxxxxxxxxxxx.apigateway.us-ashburn-1.oci.customer-oci.com/path_index/path' \
--header 'Content-Type: text/plain' \
--header 'header: header' \
--header 'header2: header2' \
--header 'header3: header3' \
--data '{"data": {"clientID": "xxxxxxxxxxxxxxxxxxx", "secretID": "xxxxxxxxxxxxxxxxxxx", "jList":[{"added_by":"Ani","description":"example description.","start_date":"2014-10-10","mark":255,"id":975}, {"added_by":"Ani","description":"example description.","start_date":"2014-10-10","mark":255,"id":975}]}}' -i
相關連結
認可
- 作者 - Cristiano Hoshikawa (Oracle LAD A 團隊解決方案工程師)
其他學習資源
瀏覽 docs.oracle.com/learn 的其他實驗室,或前往 Oracle Learning YouTube 頻道存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。
如需產品文件,請造訪 Oracle Help Center 。
Use OCI API Gateway, Functions and Observability to Validate JSON Content and Monitor API Headers and Body
F89782-01
November 2023
Copyright © 2023, Oracle and/or its affiliates.