瞭解如何叫用經驗證的 Cloud Functions

1. 簡介

總覽

Cloud Functions 是一個輕量的運算解決方案,可讓開發人員建立獨立的單一用途函式,這些函式可使用 HTTPS 觸發,或回應 CloudEvents,完全不需要管理伺服器或執行階段環境。

控管 Cloud Functions 叫用的方法主要有兩種,分別是根據身分保護存取權,以及使用以網路為基礎的存取權控管保護存取安全。本程式碼研究室著重於第一種方法,並逐步說明下列 3 種情境,以依據身分叫用函式:

  1. 使用 gcloud 身分憑證叫用本機開發的函式,測試目的
  2. 在本機開發及測試時模擬服務帳戶,使用與實際工作環境相同的憑證
  3. 使用 Google 用戶端程式庫處理 Google Cloud API 的驗證作業,例如服務需要叫用函式時

課程內容

  • 如何為 Cloud 函式設定驗證機制,並已正確設定驗證功能
  • 提供 gcloud 身分的憑證,從本機開發環境叫用已驗證的函式
  • 如何建立服務帳戶並授予叫用函式的適當角色
  • 如何從具有適當角色叫用函式的本機開發環境模擬服務

2. 設定和需求

必要條件

  • 您已登入 Cloud 控制台
  • 您先前已部署以 HTTP 觸發的第 2 代 Cloud 函式
  • (選用) 在第 3 個情境中,本程式碼研究室使用 Node.jsnpm 範例,但您可以使用 Google 驗證用戶端程式庫支援的任何執行階段。

啟用 Cloud Shell

  1. 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 853e55310c205094.png

55efc1aaa7a4d3ad.png

如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」

9c92662c6a846a5c.png

佈建並連線至 Cloud Shell 只需幾分鐘的時間。

9f0e51b578fecce5.png

這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。

連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。

  1. 在 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`
  1. 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project

指令輸出

[core]
project = <PROJECT_ID>

如果尚未設定,請使用下列指令進行設定:

gcloud config set project <PROJECT_ID>

指令輸出

Updated property [core/project].

3. 建立及測試通過驗證的 Cloud 函式

本程式碼研究室遵循 Cloud Functions 適用的 Cloud Functions 快速入門導覽課程的操作說明,但有一個值得注意的例外狀況:您的函式需要驗證。

要求驗證是指叫用函式的原則必須具備 Cloud Functions 叫用者 (以及第 2 代的 Cloud Run 叫用者) 角色;否則,函式會傳回「403 禁止」錯誤。本程式碼研究室會說明如何依據原則授予適當的叫用者角色

建立已驗證的函式

使用 Cloud 控制台的步驟如下:

  1. 前往「Cloud Functions 總覽」頁面,然後按一下「建立函式」
  2. 在「環境」選項下方,選取「第 2 代」
  3. 將函式命名為 my-authenticated-function
  4. 將「Authentication」(驗證) 欄位中的預設設定保留為「Require authentication」(需要驗證)

936eee0d5930d12b.png

  1. 點選 [下一步]。
  2. 在本程式碼研究室中,您可以選擇任何語言
  3. 然後按一下「Deploy」(部署)

部署函式大約需要 1 分鐘。

設定本機環境變數以簡化 gcloud 指令

首先,您將建立幾個環境變數,以提高這個程式碼研究室中使用的 gcloud 指令可讀性。

您應指定函式的區域。本範例使用 us-central1

REGION="us-central1"

然後,您可以將函式網址儲存為環境變數,以供日後使用。

PROJECT_ID=$(gcloud config get-value project)
FUNCTION_URL="$(gcloud functions describe my-authenticated-function --gen2 --region us-central1 --format='get(serviceConfig.uri)')"

嘗試以匿名呼叫端叫用,驗證函式需要驗證

您將在不驗證的情況下叫用函式,驗證是否收到預期的 403 錯誤。

在指令列中執行下列 curl 指令:

curl $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`

確認您使用正確的身分後,請將帳戶電子郵件儲存至環境變數。

ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")

如要進一步瞭解如何設定 gcloud initgcloud auth login,請參閱說明文件。

接著,叫用函式並傳遞您的識別權杖。

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"

您現在會看到結果:

Hello World!

疑難排解

如果收到「403 禁止」錯誤,請確認您的身分具備第 2 代函式的 Cloud Functions 叫用者角色Cloud Run 叫用者角色。您可以使用 IAM 控制台驗證指派給主體的角色。

雖然在開發期間使用自己的識別憑證可讓您快速測試函式,但受驗證函式的呼叫者需要適當的角色。否則呼叫端會收到「403 禁止」錯誤。

建議您遵循最低權限原則,限制具有叫用函式的身分及服務帳戶數量。

建立新的服務帳戶並授予必要的角色,

5. 情境 2:模擬服務帳戶

在此情況下,您將模擬服務帳戶 (亦即假設其權限) 在本機開發及測試時叫用函式。您可以模擬服務帳戶,測試函式的憑證與實際工作環境相同。

這樣一來,您不僅能驗證角色,也遵循最低權限原則,不必基於本機測試目的將 Cloud 函式叫用者角色授予其他身分。

在本程式碼研究室中,您將建立一個新的服務帳戶,其中僅有角色可叫用您在本程式碼研究室中建立的函式。

建立新的服務帳戶

首先,您將建立幾個其他環境變數,代表在 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 Function Authentication codelab"

並授予服務帳戶 Cloud 函式叫用者角色

gcloud functions add-iam-policy-binding my-authenticated-function \
  --region=us-central1 --gen2 \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/cloudfunctions.invoker'

模擬服務帳戶來叫用函式

為此,您必須取得其 ID 權杖,以模擬新建立的服務帳戶。

新增模擬要求的必要角色

如要模擬服務帳戶,您的使用者帳戶須具備服務帳戶權杖建立者 (roles/iam.serviceAccountTokenCreator) 角色,才能為服務帳戶產生 ID 權杖。

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 驗證用戶端程式庫應用程式預設憑證 (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 的步驟:

  1. 建立新的 Node.js 應用程式
npm init
  1. 安裝 Google Auth 用戶端程式庫
npm install google-auth-library
  1. 建立 index.js 檔案
  2. 擷取 Cloud 函式的網址,您將在後續步驟中加進程式碼。
echo $FUNCTION_URL
  1. 將下列程式碼加入 index.js。請務必將 targetAudience 變數變更為您的 Cloud 函式網址。

index.js

// Cloud Functions uses your function's url as the `targetAudience` value

const targetAudience = '<YOUR-CLOUD-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;
});
  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 Functions

我們也建議這篇有關使用 Cloud Functions 進行本機開發作業的網誌文章,瞭解如何在本機開發人員環境中開發及測試 Cloud 函式。

涵蓋內容

  • 如何為 Cloud 函式設定驗證機制,並已正確設定驗證功能
  • 提供 gcloud 身分的憑證,從本機開發環境叫用已驗證的函式
  • 如何建立服務帳戶並授予叫用函式的適當角色
  • 如何從具有適當角色叫用函式的本機開發環境模擬服務

8. 清除所用資源

為避免產生意外費用 (例如這個 Cloud 函式意外叫用的次數超過免費方案的每月 Cloud 函式叫用分配數量),您可以刪除 Cloud 函式或刪除步驟 2 中建立的專案。

如要停止模擬服務帳戶,您可以使用自己的身分重新登入:

gcloud auth application-default login

如要刪除 Cloud 函式,請前往 https://console.cloud.google.com/functions/ 前往 Cloud 函式 Cloud 控制台,並確認目前選取的是步驟 2 中建立的專案。

選取您先前部署的 my-authenticated-function。然後按「刪除」

如果選擇刪除整個專案,您可以前往 https://console.cloud.google.com/cloud-resource-manager,選取您在步驟 2 建立的專案,然後選擇「刪除」。如果刪除專案,您必須變更 Cloud SDK 中的專案。您可以執行 gcloud projects list 來查看可用專案的清單。