在 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
或urllib2
Python 程式庫,或 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 權杖。驗證這個權杖時,權杖酬載會包含新服務帳戶的電子郵件地址。