使用服務帳戶以「應用程式指令碼」專案身分進行驗證

本指南說明在 Apps Script 中呼叫 API 時,如何透過服務帳戶進行驗證。

服務帳戶是由應用程式使用,而非真人。您可以透過服務帳戶存取資料、以機器人帳戶執行動作,或代表 Google Workspace 或 Cloud Identity 使用者存取資料。詳情請參閱「瞭解服務帳戶」。

如要瞭解 Google Workspace API 的驗證程序,請參閱「建立存取憑證」。

在 Apps Script 中使用服務帳戶的時機

以下是您可能考慮使用服務帳戶驗證,而非其他驗證方法 (例如 ScriptApp.getOAuthToken()) 的原因:

  • 透過 Google Cloud API 和服務提升效能:許多 Google Cloud API 都是專為服務帳戶驗證而設計。服務帳戶也能提供更整合、可靠且安全的方式,與大多數 API 互動。
  • 權限分離:服務帳戶有自己的權限,與任何使用者無關。與其他使用者共用 Apps Script 專案時,驗證方法 ScriptApp.getOAuthToken() 可能會失敗。使用服務帳戶,即可共用指令碼並發布為 Google Workspace 外掛程式
  • 自動化指令碼和長時間執行的工作:服務帳戶可讓您執行自動化指令碼、批次程序或背景工作,不必輸入任何內容。
  • 提升安全性並採用最低權限原則:您可以授予服務帳戶特定權限,僅提供所需資源的存取權。這符合最小權限原則,可降低安全風險。使用 ScriptApp.getOAuthToken() 通常會授予指令碼所有使用者權限,這可能過於廣泛。
  • 集中式存取權管理:服務帳戶是使用 Google Cloud 的 Identity and Access Management (IAM) 管理。IAM 可協助 Google Workspace 機構管理 Apps Script 專案中已驗證服務的存取權。

必要條件

建立服務帳戶

在 Cloud 專案中建立服務帳戶:

Google Cloud 控制台

  1. 在 Google Cloud 控制台中,依序前往「選單」圖示 >「IAM 與管理」 >「服務帳戶」

    前往「Service Accounts」(服務帳戶) 頁面

  2. 按一下「建立服務帳戶」
  3. 填寫服務帳戶詳細資料,然後按一下「建立並繼續」
  4. 選用步驟:將角色指派給服務帳戶,授予 Google Cloud 專案資源的存取權。詳情請參閱「授予、變更及撤銷資源的存取權」。
  5. 按一下「繼續」
  6. 選用:輸入可管理這個服務帳戶及執行動作的使用者或群組。詳情請參閱「管理服務帳戶模擬功能」。
  7. 按一下「完成」,請記下服務帳戶的電子郵件地址。

gcloud CLI

  1. 建立服務帳戶:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. 選用步驟:將角色指派給服務帳戶,授予 Google Cloud 專案資源的存取權。詳情請參閱「授予、變更及撤銷資源的存取權」。

將角色指派給服務帳戶

您必須透過超級管理員帳戶,將預先建立的角色或自訂角色指派給服務帳戶。

  1. 在 Google 管理控制台中,依序點選「選單」圖示 > 「帳戶」>「管理員角色」

    前往「管理員角色」

  2. 將滑鼠游標移至要指派的角色,然後按一下「指派管理員」

  3. 按一下「指派服務帳戶」

  4. 輸入服務帳戶的電子郵件地址。

  5. 依序點選「新增」>「指派角色」

建立服務帳戶的憑證

您需要取得公開/私密金鑰組形式的憑證。程式碼會使用這些憑證,授權應用程式中的服務帳戶動作。

如要取得服務帳戶的憑證,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中,依序前往「Menu」(選單) >「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)

    前往「Service Accounts」(服務帳戶) 頁面

  2. 選取服務帳戶。
  3. 依序點選「金鑰」>「新增金鑰」>「建立新的金鑰」
  4. 選取「JSON」,然後按一下「建立」

    接著,系統就會為您產生一對新的公開/私密金鑰,並以新檔案的形式下載至您的電腦中。將下載的 JSON 檔案儲存為工作目錄中的 credentials.json。這個檔案是這組金鑰的唯一副本,如要瞭解如何安全儲存金鑰,請參閱「管理服務帳戶金鑰」一文。

  5. 點選「關閉」

複製 Cloud 專案編號

  1. 在 Google Cloud 控制台中,依序前往「Menu」(選單) >「IAM & Admin」(IAM 與管理) >「Settings」(設定)

    前往「IAM & Admin Settings」(IAM 與管理員設定)

  2. 在「專案編號」欄位中,複製該值。

在 Apps Script 專案中設定服務帳戶驗證

本節說明如何將 Cloud 專案中的服務帳戶憑證新增至 Apps Script 專案。

在 Apps Script 中設定雲端專案

  1. 前往 Apps Script 開啟或建立專案:


    開啟 Apps Script

  2. 在 Apps Script 專案中,按一下「專案設定」專案設定圖示

  3. 點選「Google Cloud Platform (GCP) 專案」下方的「變更專案」

  4. 在「GCP 專案編號」中,貼上 Google Cloud 專案編號。

  5. 點選「設定專案」

將憑證儲存為指令碼屬性

將服務帳戶憑證儲存為 Apps Script 專案設定中的指令碼屬性,確保憑證安全無虞:

  1. 複製您在上一節建立的服務帳戶 JSON 檔案內容 (credentials.json)。
  2. 在 Apps Script 專案中,前往「專案設定」
  3. 前往「專案設定」頁面,然後前往「指令碼屬性」,按一下「新增指令碼屬性」,並輸入下列內容:
    • 在「Property」(屬性) 欄位中輸入 SERVICE_ACCOUNT_KEY
    • 在「值」欄位中,貼上 JSON 金鑰檔案的內容。
  4. 按一下「儲存指令碼屬性」

新增 OAuth2 程式庫

如要處理 OAuth2 驗證流程,可以使用 Apps Script 程式庫 apps-script-oauth2

如要將程式庫新增至 Apps Script 專案,請按照下列步驟操作:

  1. 在 Apps Script 編輯器中,按一下左側「程式庫」旁的「新增程式庫」圖示
  2. 在「Script ID」(指令碼 ID) 欄位中輸入 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
  3. 按一下「查詢」
  4. 選取最新版本,然後按一下「新增」

使用服務帳戶憑證呼叫 API

如要使用 Apps Script 專案中的服務帳戶憑證,可以使用下列函式 getServiceAccountService()

/**
 * Get a new OAuth2 service for a given service account.
 */
function getServiceAccountService() {
  const serviceAccountKeyString = PropertiesService.getScriptProperties()
      .getProperty('SERVICE_ACCOUNT_KEY');

  if (!serviceAccountKeyString) {
    throw new Error('SERVICE_ACCOUNT_KEY property is not set. ' +
        'Please follow the setup instructions.');
  }

  const serviceAccountKey = JSON.parse(serviceAccountKeyString);

  const CLIENT_EMAIL = serviceAccountKey.client_email;
  const PRIVATE_KEY = serviceAccountKey.private_key;

  // Replace with the specific scopes required for your API.
  const SCOPES = ['SCOPE'];

  return OAuth2.createService('ServiceAccount')
      .setTokenUrl('https://oauth2.googleapis.com/token')
      .setPrivateKey(PRIVATE_KEY)
      .setIssuer(CLIENT_EMAIL)
      .setPropertyStore(PropertiesService.getScriptProperties())
      .setScope(SCOPES);
}

SCOPE 替換成呼叫 API 時所需的授權範圍。指令碼會使用您在上一個步驟中儲存為 SERVICE_ACCOUNT_KEY 指令碼屬性的服務帳戶憑證。

接著,您可以使用這些憑證呼叫 API,如下列 UrlFetch 服務的範例所示:

function callApi() {
  const service = getServiceAccountService();

  // TODO(developer): Replace with the payload
  const payload = {};

  // TODO(developer): Replace with the API endpoint
  const response = UrlFetchApp.fetch('API_URL', {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${service.getAccessToken()}`,
      'Content-Type': 'application/json',
    },
    payload: payload,
  });

  const result = JSON.parse(response.getContentText());

  return result;
}

API_URL 替換為您要呼叫的 HTTP 端點。