1. 簡介
總覽
Cloud Run 函式是輕量運算解決方案,可讓開發人員建立可使用 HTTPS 觸發或回應 CloudEvents 的單一用途獨立函式,不必管理伺服器或執行階段環境。如要進一步瞭解 Cloud Run 函式,請參閱我們的網誌文章。
控制 Cloud Run 函式叫用有兩種主要方法:根據身分保護存取權,以及使用網路式存取權控管保護存取權。本程式碼研究室著重於第一種方法,並引導您瞭解 3 種情況,說明如何根據身分確保存取權,以便叫用函式:
- 使用 gcloud 身分權杖,針對本機開發和測試目的叫用函式
- 在本機開發及測試時,模擬服務帳戶,以便使用與正式版相同的憑證
- 使用 Google 用戶端程式庫處理 Google Cloud API 的驗證作業,例如當服務需要叫用函式時
課程內容
- 如何設定 Cloud Run 函式的驗證機制,並確認驗證機制已正確設定
- 提供 gcloud 身分的憑證,從本機開發環境叫用已驗證的函式
- 如何建立服務帳戶,並授予適當的角色以叫用函式
- 如何從具有適當函式叫用角色的本機開發環境,模擬服務
2. 設定和需求
必要條件
- 您已登入 Cloud Console
- 您之前已部署由 HTTP 觸發的 Cloud Run 函式。查看快速入門導覽課程範例。
- (選用) 在第 3 種情況下,本程式碼研究室使用 Node.js 和 npm 做為範例,但您可以使用 Google Auth 用戶端程式庫支援的任何執行階段。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」 圖示
。
如果這是您首次啟動 Cloud Shell,系統會顯示中介畫面,說明 Cloud Shell 的功能。如果您看到中介畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 的作業只需幾分鐘的時間。
這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,可大幅提升網路效能和驗證功能。您可以在瀏覽器中完成本程式碼研究室的大部分工作,甚至是全部工作。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 Cloud Shell 中執行下列指令,確認您已通過驗證:
gcloud auth list
指令輸出
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project
指令輸出
[core] project = <PROJECT_ID>
如果尚未設定,請使用下列指令進行設定:
gcloud config set project <PROJECT_ID>
指令輸出
Updated property [core/project].
3. 建立及測試經過驗證的 Cloud Run 函式
要求驗證機制,表示叫用函式的原則必須具有 Cloud Run 叫用者角色;否則,函式會傳回 403 Forbidden 錯誤。本程式碼研究室將說明如何將適當的 Invoker 角色授予原則。
設定本機環境變數以簡化 gcloud 指令
首先,您將建立幾個環境變數,以提高這個程式碼研究室中使用的 gcloud
指令可讀性。
REGION=us-central1 PROJECT_ID=$(gcloud config get-value project)
建立函式原始碼
雖然本程式碼研究室使用 Node.js,但您可以使用 Google 驗證用戶端程式庫支援的任何執行階段。
首先,請建立目錄並使用 cd 命令進入該目錄。
mkdir auth-function-codelab && cd $_
然後建立 package.json 檔案。
touch package.json echo '{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0" } } ' > package.json
接下來,請建立 index.js 來源檔案。
touch index.js echo 'const functions = require("@google-cloud/functions-framework"); functions.http("helloWorld", (req, res) => { res.send(`Hello ${req.query.name || req.body.name || "World"}!`); });' > index.js
建立已驗證的函式
以下是為 nodejs20 執行階段建立已驗證的函式步驟。不過,您可以使用 Google Auth 用戶端程式庫支援的任何執行階段。
FUNCTION_NAME=authenticated-function-codelab ENTRY_POINT=helloWorld
如要將 Cloud Run 函式直接部署至 Cloud Run,請執行下列指令:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function helloWorld \ --region $REGION \ --no-allow-unauthenticated
然後將函式網址儲存為環境變數,以供日後使用。
FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"
如果您想部署 Cloud Functions 第 2 代,請使用下列指令:
gcloud functions deploy nodejs-http-function \ --gen2 \ --runtime=nodejs20 \ --region=$REGION \ --source=. \ --entry-point=helloWorld \ --trigger-http \ --no-allow-unauthenticated
然後將函式網址儲存為環境變數,以供稍後使用。
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"
嘗試以匿名呼叫端的身份叫用函式,驗證函式是否需要驗證
您將在不驗證的情況下叫用函式,確認您收到預期的 403 錯誤。
在指令列中執行下列 curl
指令:
curl -i $FUNCTION_URL
您會看到以下結果:
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Your client does not have permission to get URL <code>/</code> from this server.</h2> <h2></h2> </body></html>
您現在已準備好逐步瞭解可以透過提供驗證來叫用函式的 3 種情境。
4. 情境 1:使用 gcloud 身分權杖
開發人員需要在本機開發函式時測試函式。在本節中,您將執行快速測試,驗證函式是否能使用您自己的身分進行適當驗證。
執行下列指令,確認您已使用 gcloud
進行驗證:
gcloud auth list
您會在有效身分旁看到星號,例如:
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
如要進一步瞭解如何設定 gcloud init 和 gcloud auth login,請參閱說明文件。
接下來,請叫用函式並傳遞您的身分識別碼。
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"
您現在會看到結果:
Hello World!
疑難排解
如果您收到 403 Forbidden 錯誤,請確認您的身分具有 Cloud Run 叫用者角色。您可以使用 IAM 控制台驗證主體的角色。
雖然使用您自己的身分驗證權杖是開發期間測試函式的快速方法,但已驗證函式的呼叫端需要適當的角色,否則呼叫端會收到 403 Forbidden 錯誤。
您應該遵循最小權限原則,限制具有可叫用函式的角色身分和服務帳戶數量。在下一個情境中,您將學習如何建立新的服務帳戶,並授予叫用函式所需的適當角色。
5. 情境 2:模擬服務帳戶
在此情況下,您將模擬服務帳戶 (亦即假設其權限) 在本機開發及測試時叫用函式。您可以模擬服務帳戶,以正式版相同的憑證測試函式。
這樣一來,您不但可以驗證角色,還能遵循最小權限原則,不必為了本機測試目的,將 Cloud Functions 叫用者角色授予其他身分。
為了完成這個程式碼研究室,您將建立一個新的服務帳戶,該帳戶只具備用於叫用您在這個程式碼研究室中建立的函式的角色。
建立新的服務帳戶
首先,您將建立幾個額外的環境變數,用來代表 gcloud 指令中使用的服務帳戶。
SERVICE_ACCOUNT_NAME="invoke-functions-codelab" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
接下來,您將建立服務帳戶。
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \ --display-name="Cloud Run function Authentication codelab"
並授予服務帳戶 Cloud Run 叫用者角色:
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --region=us-central1 \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/run.invoker'
模擬服務帳戶來叫用函式
為此,您需取得其 ID 權杖,以模擬新建立的服務帳戶。
新增模擬要求的必要角色
如要冒用服務帳戶,您的使用者帳戶必須具備服務帳戶憑證建立者 (roles/iam.serviceAccountTokenCreator) 角色,才能為服務帳戶產生 ID 權杖。
您可以執行下列指令,為有效使用者帳戶授予這個角色:
ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)") gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS \ --member user:$ACCOUNT_EMAIL \ --role='roles/iam.serviceAccountTokenCreator'
使用服務帳戶的 ID 權杖
請稍候幾分鐘,讓權限生效。您現在可以傳遞服務帳戶的 ID 權杖來叫用函式。
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)"
您會看到以下畫面:
WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com]. Hello World!
6. 情境 3:使用 Google 用戶端程式庫
在本程式碼研究室的最後部分,您將在本機執行小型服務,為服務帳戶產生 ID 權杖,然後使用 Google Auth 用戶端程式庫和應用程式預設憑證 (ADC),以程式輔助方式呼叫該函式。如要進一步瞭解 Google 用戶端程式庫,請參閱說明文件的用戶端程式庫說明部分。
如果您想在本機 (例如筆電、Cloud Shell 等) 編寫及測試函式,同時與其他 Google Cloud 資源 (例如 Cloud Storage、Vision API 等) 互動,使用 ADC 就特別重要。在本例中,您將瞭解如何讓服務叫用需要驗證的其他函式。如要進一步瞭解 ADC 和本機開發作業,請參閱這篇網誌文章:如何在本機開發及測試 Cloud Functions | Google Cloud 網誌
執行 gcloud 指令,模擬服務帳戶
ADC 會根據應用程式環境自動尋找憑證,並使用這些憑證向 Google Cloud API 進行驗證。「repersonate-service-account 旗標」可讓您使用服務帳戶的身分,透過服務帳戶驗證 Google Cloud API,藉此冒用服務帳戶。
如要冒用服務帳戶,您可以執行下列指令:
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
您現在是以服務帳戶 (而非身分) 的身分執行 gcloud 指令。
建立並執行服務以叫用已驗證的函式
每個執行階段都有可安裝的 Google 驗證用戶端程式庫。本程式碼研究室會引導您逐步完成在本機建立及執行 Node.js 應用程式的程序。
以下是 Node.js 的步驟:
- 建立新目錄
mkdir local-dev && cd $_
- 建立新的 Node.js 應用程式
npm init -y
- 安裝 Google 驗證用戶端程式庫
npm install google-auth-library
- 建立
index.js
檔案 - 擷取 Cloud Run 函式的網址,您會在下一個步驟中將網址加入程式碼。
echo $FUNCTION_URL
- 將下列程式碼加入 index.js。請務必將 targetAudience 變數變更為 Cloud Run 函式網址。
index.js
// Cloud Functions uses your function's url as the `targetAudience` value
const targetAudience = '<YOUR-CLOUD-RUN-FUNCTION-URL>';
// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal
const url = targetAudience;
const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();
async function request() {
console.info(`request ${url} with target audience ${targetAudience}`);
// this call retrieves the ID token for the impersonated service account
const client = await auth.getIdTokenClient(targetAudience);
const res = await client.request({ url });
console.info(res.data);
}
request().catch(err => {
console.error(err.message);
process.exitCode = 1;
});
- 執行應用程式
node index.js
您應該會看到「Hello World!」
疑難排解
如果您看到「權限『iam.serviceAccounts.getOpenIdToken』已拒絕 (或可能不存在)」錯誤訊息,請稍待幾分鐘,讓「服務帳戶符記建立者」角色套用。
如果您收到「無法在這個環境中擷取 ID 權杖」錯誤訊息,請使用 GCE 或將 GOOGLE_APPLICATION_CREDENTIALS 環境變數設為服務帳戶憑證 JSON 檔案,您可能忘記執行以下指令
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
7. 恭喜!
恭喜您完成本程式碼研究室!
建議您參閱說明文件,瞭解如何保護 Cloud Run 函式。
我們也建議您參閱這篇部落格文章,瞭解如何在本機開發環境中開發及測試 Cloud Run 函式。
涵蓋內容
- 如何為 Cloud Run 函式設定驗證機制及驗證驗證設定正確
- 提供 gcloud 身分的憑證,從本機開發環境叫用已驗證的函式
- 如何建立服務帳戶,並授予適當的角色以叫用函式
- 如何從具有適當函式叫用角色的本機開發環境,模擬服務
8. 清理
為避免產生意外費用 (例如,這個 Cloud 函式不小心叫用次數超過 免費等級的 Cloud Run 函式叫用次數配額),您可以刪除 Cloud 函式,或是刪除在步驟 2 中建立的專案。
如要停止模擬服務帳戶,您可以使用自己的身分重新登入:
gcloud auth application-default login
如要刪除 Cloud Run 函式,請前往 Cloud Run 函式 Cloud 控制台 (https://console.cloud.google.com/functions/)。請確認目前選取的專案是您在步驟 2 中建立的專案。
選取您先前部署的 my-authenticated-function。然後按一下「刪除」。
如果您選擇刪除整個專案,可以前往 https://console.cloud.google.com/cloud-resource-manager,選取您在步驟 2 中建立的專案,然後選擇「Delete」(刪除)。如果您刪除專案,就必須在 Cloud SDK 中變更專案。您可以執行 gcloud projects list
來查看可用專案的清單。