在 Python 2 執行階段中執行的應用程式向其他 App Engine 應用程式傳送要求時,可以使用 App Engine App Identity API 宣告自己的身分。接收要求的應用程式可以使用這個身分,判斷是否應處理要求。
如果 Python 3 應用程式在傳送要求給其他 App Engine 應用程式時需要聲明身分,可以使用由 Google OAuth 2.0 API 發行及解碼的 OpenID Connect (OIDC) ID 權杖。
以下簡要說明如何使用 OIDC ID 權杖來聲明及驗證身分:
- 名為「App A」的 App Engine 應用程式會從 Google Cloud 執行階段環境擷取 ID 權杖。
- 應用程式 A 會在將要求傳送至另一個 App Engine 應用程式 B 之前,將這個權杖新增至要求標頭。
- 應用程式 B 會使用 Google 的 OAuth 2.0 API 驗證權杖酬載。解碼後的酬載包含應用程式 A 的已驗證身分,也就是應用程式 A 預設服務帳戶的電子郵件地址。
- 應用程式 B 會將酬載中的身分與允許回應的身分清單進行比較。如果要求來自允許的應用程式,應用程式 B 會處理要求並做出回應。
 
本指南說明如何更新 App Engine 應用程式,使用 OpenID Connect (OIDC) ID 權杖來聲明身分,以及更新其他 App Engine 應用程式,在處理要求前使用 ID 權杖驗證身分。
App Identity API 與 OIDC API 的主要差異
- Python 2 執行階段中的應用程式不需要明確聲明身分。當應用程式使用 - httplib、- urllib或- urllib2Python 程式庫,或 App Engine 網址擷取服務傳送輸出要求時,執行階段會使用 App Engine 網址擷取服務發出要求。如果要求傳送至- appspot.com網域,網址擷取服務會自動在要求中加入- X-Appengine-Inbound-Appid標頭,以聲明要求應用程式的身分。該標頭包含應用程式 ID (也稱為專案 ID)。- Python 3 執行階段中的應用程式必須從 Google Cloud 執行階段環境擷取 OIDC ID 權杖,並將其加入要求標頭,才能明確聲明身分。您必須更新所有會將要求傳送至其他 App Engine 應用程式的程式碼,確保要求包含 OIDC ID 權杖。 
- 要求中的 - X-Appengine-Inbound-Appid標頭包含傳送要求的應用程式專案 ID。- Google OIDC ID 權杖的酬載不會直接識別應用程式本身的專案 ID。而是提供服務帳戶的電子郵件地址,藉此識別應用程式執行的服務帳戶。您需要新增一些程式碼,從權杖酬載中擷取使用者名稱。 - 如果該服務帳戶是專案的應用程式層級預設 App Engine 服務帳戶,則專案 ID 會顯示在服務帳戶的電子郵件地址中。地址的使用者名稱部分與專案 ID 相同。在本例中,接收端應用程式程式碼可以在允許要求的專案 ID 清單中,查詢這個 ID。 - 不過,如果提出要求的應用程式使用使用者管理的服務帳戶,而非預設的 App Engine 服務帳戶,則接收應用程式只能驗證該服務帳戶的身分,這不一定會定義提出要求應用程式的專案 ID。在這種情況下,接收應用程式必須維護允許的服務帳戶電子郵件地址清單,而不是允許的專案 ID 清單。 
- URL Fetch API 呼叫的配額與 Google OAuth 2.0 API 的配額不同,後者用於授予權杖。您可以在Google Cloud 控制台 OAuth 同意畫面中,查看每日可授予的符記數量上限。URL Fetch、App Identity API 和 Google 的 OAuth 2.0 API 都不會產生費用。 
轉換程序總覽
如要遷移 Python 應用程式,改用 OIDC API 聲明及驗證身分,請按照下列步驟操作:
- 在需要向其他 App Engine 應用程式傳送要求時宣告身分的應用程式中: - 請等到應用程式在 Python 3 環境中執行後,再遷移至 ID 權杖。 - 雖然可以在 Python 2 執行階段中使用 ID 權杖,但 Python 2 的步驟很複雜,而且您只需要暫時使用,直到將應用程式更新為在 Python 3 執行階段中執行為止。 
- 應用程式在 Python 3 中執行後,請更新應用程式,要求 ID 權杖並將權杖新增至要求標頭。 
 
- 在需要先驗證身分才能處理要求的應用程式中: - 首先,請將 Python 2 應用程式升級為同時支援 ID 權杖和 App Identity API 身分識別。這樣一來,應用程式就能驗證及處理來自 Python 2 應用程式 (使用 App Identity API) 或 Python 3 應用程式 (使用 ID 權杖) 的要求。 
- 升級後的 Python 2 應用程式穩定運作後,請將其遷移至 Python 3 執行階段。請繼續支援 ID 權杖和 App Identity API 身分,直到確定應用程式不再需要支援舊版應用程式的要求為止。 
- 如果不再需要處理舊版 App Engine 應用程式的要求,請移除驗證 App Identity API 身分的程式碼。 
 
- 測試應用程式後,請先部署處理要求的應用程式。然後部署更新後的 Python 3 應用程式,使用 ID 權杖來聲明身分。 
聲明身分
等待應用程式在 Python 3 環境中執行,然後按照下列步驟升級應用程式,以使用 ID 權杖聲明身分:
為 Python 3 應用程式安裝 google-auth 用戶端程式庫
如要讓 Python3 應用程式使用 google-auth 用戶端程式庫,請在與 app.yaml 檔案相同的資料夾中建立 requirements.txt 檔案,然後加入下列程式碼:
     google-auth
部署應用程式時,App Engine 會下載 requirements.txt 檔案中定義的所有依附元件。
進行本機開發時,建議您在虛擬環境 (例如 venv) 中安裝依附元件。
新增程式碼來聲明身分
搜尋程式碼,找出所有傳送要求至其他 App Engine 應用程式的執行個體。請先更新這些執行個體,再傳送要求:
- 新增下列匯入項目: - from google.auth.transport import requests as reqs from google.oauth2 import id_token
- 使用 - google.oauth2.id_token.fetch_id_token(request, audience)擷取 ID 權杖。在方法呼叫中加入下列參數:- request:傳遞您即將傳送的要求物件。
- audience:傳遞要傳送要求的應用程式網址。 這會將權杖繫結至要求,防止權杖遭其他應用程式使用。- 為求清楚明確,建議您傳遞 App Engine 為接收要求的特定服務建立的網址,即使您使用應用程式的自訂網域也一樣。 - appspot.com
 
- 在要求物件中,設定下列標頭: - 'Authorization': 'ID {}'.format(token)
例如:
聲明身分測試更新
如要在本機執行應用程式,並測試應用程式是否能順利傳送 ID 權杖,請按照下列步驟操作:
- 請按照下列步驟操作,在您的本機環境中提供預設 App Engine 服務帳戶的憑證 (Google OAuth API 需要這些憑證才能產生 ID 權杖): - 輸入下列 - gcloud指令,擷取專案預設 App Engine 帳戶的服務帳戶金鑰:- gcloud iam service-accounts keys create ~/key.json --iam-account project-ID@appspot.gserviceaccount.com- 將 project-ID 替換為專案 ID。Google Cloud - 服務帳戶金鑰檔案會下載到您的機器中,您可以任意移動及重新命名此檔案。請務必妥善保存這個檔案,因為此檔案可當做服務帳戶進行驗證。如果遺失檔案或檔案遭未經授權的使用者存取,請刪除服務帳戶金鑰並建立新的金鑰。 
- 輸入下列指令: - <code>export GOOGLE_APPLICATION_CREDENTIALS=<var>service-account-key</var></code>
 - 將 service-account-key 替換為含有您下載服務帳戶金鑰的檔案絕對路徑名稱。 
- 在匯出 - GOOGLE_APPLICATION_CREDENTIALS環境變數的相同殼層中,啟動 Python 應用程式。
- 從應用程式傳送要求,並確認要求成功。如果您沒有可接收要求並使用 ID 權杖驗證身分的應用程式: - 下載「來電」範例應用程式。
- 在範例的 - main.py檔案中,將 Google Cloud 專案的 ID 新增至- allowed_app_ids。例如:- allowed_app_ids = [ '<APP_ID_1>', '<APP_ID_2>', 'my-project-id' ]
- 在 Python 2 本機開發伺服器中執行更新後的範例。 
 
驗證及處理要求
如要升級 Python 2 應用程式,在處理要求前使用 ID 權杖或 App Identity API 身分:
- 安裝 google-auth 用戶端程式庫。 
- 更新程式碼,執行下列操作: - 如果要求包含 - X-Appengine-Inbound-Appid標頭,請使用該標頭驗證身分。在舊版執行階段 (例如 Python 2) 中執行的應用程式會包含這個標頭。
- 如果要求不含 - X-Appengine-Inbound-Appid標頭,請檢查 OIDC ID 符記。如果權杖存在,請驗證權杖酬載並檢查傳送者的身分。
 
- 測試更新。 
為 Python 2 應用程式安裝 google-auth 用戶端程式庫
如要讓 Python 2 應用程式使用 google-auth 用戶端程式庫,請按照下列步驟操作:
- 在與 - app.yaml檔案相同的資料夾中建立- requirements.txt檔案,並新增下列程式碼:- google-auth==1.19.2- 建議您使用 Cloud Logging 用戶端程式庫 1.19.2 版,因為該版本支援 Python 2.7 應用程式。 
- 在應用程式的 - app.yaml檔案中,於- libraries區段指定 SSL 程式庫 (如果尚未指定):- libraries: - name: ssl version: latest
- 建立目錄以儲存第三方程式庫,例如 - lib/。 然後使用- pip install將程式庫安裝到目錄中。 例如:- pip install -t lib -r requirements.txt 
- 在 - app.yaml檔案所在的資料夾中建立- appengine_config.py檔案。請將以下內容新增到- appengine_config.py檔案中:- # appengine_config.py import pkg_resources from google.appengine.ext import vendor # Set path to your libraries folder. path = 'lib' # Add libraries installed in the path folder. vendor.add(path) # Add libraries to pkg_resources working set to find the distribution. pkg_resources.working_set.add_entry(path) - 上述範例中的 - appengine_config.py檔案假設- lib資料夾位於目前的工作目錄。如果無法確保- lib一律位於目前的工作目錄中,請指定- lib資料夾的完整路徑。例如:- import os path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') 
進行本機開發時,建議您在虛擬環境 (例如 Python 2 的 virtualenv) 中安裝依附元件。
更新用於驗證要求的程式碼
搜尋程式碼,找出所有取得 X-Appengine-Inbound-Appid 標頭值的例項。更新這些執行個體,以執行下列操作:
- 新增下列匯入項目: - from google.auth.transport import requests as reqs from google.oauth2 import id_token
- 如果傳入的要求不含 - X-Appengine-Inbound-Appid標頭,請尋找- Authorization標頭並擷取其值。- 標頭值的格式為「ID: token」。 
- 使用 - google.oauth2.id_token.verify_oauth2_token(token, request, audience)驗證及擷取已解碼的權杖酬載。在方法呼叫中加入下列參數:- token:傳遞從傳入要求中擷取的權杖。
- request:傳遞新的- google.auth.transport.Request物件。
- audience:傳送目前應用程式的網址 (傳送驗證要求的應用程式)。Google 授權伺服器會將這個網址與原始產生權杖時提供的網址進行比較。如果網址不符,系統就不會驗證權杖,授權伺服器也會傳回錯誤。
 
- verify_oauth2_token方法會傳回已解碼的權杖酬載,其中包含多個名稱/值配對,包括產生權杖的應用程式預設服務帳戶電子郵件地址。
- 從權杖酬載中的電子郵件地址擷取使用者名稱。 - 使用者名稱與傳送要求之應用程式的專案 ID 相同。這與先前在 - X-Appengine-Inbound-Appid標頭中傳回的值相同。
- 如果使用者名稱/專案 ID 位於允許的專案 ID 清單中,請處理要求。 
例如:
身分驗證測試更新
如要測試應用程式是否能使用 ID 權杖或 X-Appengine-Inbound-Appid 標頭驗證要求,請在 Python 2 本機開發伺服器中執行應用程式,並從 Python 2 應用程式 (會使用 App Identity API) 和傳送 ID 權杖的 Python 3 應用程式傳送要求。
如果尚未更新應用程式以傳送 ID 權杖:
- 下載範例「要求」應用程式。 
- 如「測試應用程式的聲明更新」一文所述,將服務帳戶憑證新增至本機環境。 
- 使用標準 Python 3 指令啟動 Python 3 範例應用程式。 
- 從範例應用程式傳送要求,並確認要求成功。 
部署應用程式
準備好部署應用程式後,請按照下列步驟操作:
- 如果應用程式順利執行,請使用流量分配,逐步增加更新後應用程式的流量。在將更多流量導向更新後的應用程式之前,請密切監控應用程式是否有任何問題。 
使用其他服務帳戶來聲明身分
要求 ID 權杖時,要求預設會使用 App Engine 預設服務帳戶的身分。驗證權杖時,權杖酬載會包含預設服務帳戶的電子郵件地址,該地址會對應至應用程式的專案 ID。
根據預設,App Engine 預設服務帳戶的權限等級非常高。這個帳戶可以查看及編輯整個Google Cloud 專案,因此在大多數情況下,應用程式需要向 Cloud 服務驗證時,不適合使用這個帳戶。
不過,在聲明應用程式身分時,使用預設服務帳戶是安全的,因為您只會使用 ID 權杖驗證傳送要求的應用程式身分。在此程序中,系統不會考量或需要授予服務帳戶的實際權限。
如果仍想使用其他服務帳戶提出 ID 權杖要求,請按照下列步驟操作:
- 將名為 - GOOGLE_APPLICATION_CREDENTIALS的環境變數設為包含服務帳戶憑證的 JSON 檔案路徑。請參閱安全儲存這些憑證的建議。
- 使用 - google.oauth2.id_token.fetch_id_token(request, audience)擷取 ID 權杖。
- 驗證這個權杖時,權杖酬載會包含新服務帳戶的電子郵件地址。