本指南說明在 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 專案中已驗證服務的存取權。
必要條件
- Google Cloud 專案。
- 在 Cloud 專案中,啟用要使用服務帳戶憑證進行驗證的任何 API。
- 如要將角色指派給服務帳戶,您必須具備超級管理員權限。
建立服務帳戶
在 Cloud 專案中建立服務帳戶:
Google Cloud 控制台
- 在 Google Cloud 控制台中,依序前往「選單」圖示 >「IAM 與管理」 >「服務帳戶」。
- 按一下「建立服務帳戶」。
- 填寫服務帳戶詳細資料,然後按一下「建立並繼續」。
- 選用步驟:將角色指派給服務帳戶,授予 Google Cloud 專案資源的存取權。詳情請參閱「授予、變更及撤銷資源的存取權」。
- 按一下「繼續」。
- 選用:輸入可管理這個服務帳戶及執行動作的使用者或群組。詳情請參閱「管理服務帳戶模擬功能」。
- 按一下「完成」,請記下服務帳戶的電子郵件地址。
gcloud CLI
- 建立服務帳戶:
gcloud iam service-accounts createSERVICE_ACCOUNT_NAME\ --display-name="SERVICE_ACCOUNT_NAME" - 選用步驟:將角色指派給服務帳戶,授予 Google Cloud 專案資源的存取權。詳情請參閱「授予、變更及撤銷資源的存取權」。
將角色指派給服務帳戶
您必須透過超級管理員帳戶,將預先建立的角色或自訂角色指派給服務帳戶。
在 Google 管理控制台中,依序點選「選單」圖示 > 「帳戶」>「管理員角色」。
將滑鼠游標移至要指派的角色,然後按一下「指派管理員」。
按一下「指派服務帳戶」。
輸入服務帳戶的電子郵件地址。
依序點選「新增」>「指派角色」。
建立服務帳戶的憑證
您需要取得公開/私密金鑰組形式的憑證。程式碼會使用這些憑證,授權應用程式中的服務帳戶動作。如要取得服務帳戶的憑證,請按照下列步驟操作:
- 在 Google Cloud 控制台中,依序前往「Menu」(選單) >「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)。
- 選取服務帳戶。
- 依序點選「金鑰」>「新增金鑰」>「建立新的金鑰」。
- 選取「JSON」,然後按一下「建立」。
接著,系統就會為您產生一對新的公開/私密金鑰,並以新檔案的形式下載至您的電腦中。將下載的 JSON 檔案儲存為工作目錄中的
credentials.json。這個檔案是這組金鑰的唯一副本,如要瞭解如何安全儲存金鑰,請參閱「管理服務帳戶金鑰」一文。 - 點選「關閉」。
複製 Cloud 專案編號
- 在 Google Cloud 控制台中,依序前往「Menu」(選單) >「IAM & Admin」(IAM 與管理) >「Settings」(設定)。
- 在「專案編號」欄位中,複製該值。
在 Apps Script 專案中設定服務帳戶驗證
本節說明如何將 Cloud 專案中的服務帳戶憑證新增至 Apps Script 專案。
在 Apps Script 中設定雲端專案
前往 Apps Script 開啟或建立專案:
在 Apps Script 專案中,按一下「專案設定」
。
點選「Google Cloud Platform (GCP) 專案」下方的「變更專案」。
在「GCP 專案編號」中,貼上 Google Cloud 專案編號。
點選「設定專案」。
將憑證儲存為指令碼屬性
將服務帳戶憑證儲存為 Apps Script 專案設定中的指令碼屬性,確保憑證安全無虞:
- 複製您在上一節建立的服務帳戶 JSON 檔案內容 (
credentials.json)。 - 在 Apps Script 專案中,前往「專案設定」。
- 前往「專案設定」頁面,然後前往「指令碼屬性」,按一下「新增指令碼屬性」,並輸入下列內容:
- 在「Property」(屬性) 欄位中輸入
SERVICE_ACCOUNT_KEY。 - 在「值」欄位中,貼上 JSON 金鑰檔案的內容。
- 在「Property」(屬性) 欄位中輸入
- 按一下「儲存指令碼屬性」。
新增 OAuth2 程式庫
如要處理 OAuth2 驗證流程,可以使用 Apps Script 程式庫 apps-script-oauth2。
如要將程式庫新增至 Apps Script 專案,請按照下列步驟操作:
- 在 Apps Script 編輯器中,按一下左側「程式庫」旁的「新增程式庫」圖示 。
- 在「Script ID」(指令碼 ID) 欄位中輸入
1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF。 - 按一下「查詢」。
- 選取最新版本,然後按一下「新增」。
使用服務帳戶憑證呼叫 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 端點。