簡體   English   中英

如何在不下載服務帳戶憑據的情況下從 Google Compute Engine 和本地驗證 Google API(Google Drive API)?

[英]How to authenticate Google APIs (Google Drive API) from Google Compute Engine and locally without downloading Service Account credentials?

我們公司正在處理來自谷歌雲平台的谷歌表格(在谷歌雲端硬盤中)的數據,我們在身份驗證方面遇到了一些問題。

我們需要在兩個不同的地方運行對 Google Drive 進行 API 調用的代碼:在 Google Compute Engine 的生產環境中,以及在開發環境中,即在我們開發人員的本地筆記本電腦上。

我們公司對憑據非常嚴格,不允許下載服務帳戶憑據 JSON 密鑰(這是更好的做法並提供更高的安全性)。 似乎 GCP 的所有文檔都說只需下載服務帳戶的 JSON 密鑰並使用它。 或者 Google APIs/Developers 文檔說要創建一個 OAuth2 客戶端 ID 並像這里一樣下載它的密鑰。
他們經常使用這樣的代碼:

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

但是我們不能(或者只是不想)下載我們的服務帳戶 JSON 密鑰,所以如果我們只是按照文檔進行操作,我們就會陷入困境。

對於 Google Compute Engine 環境,我們已經能夠使用 GCP 應用程序默認憑證 (ADC) 進行身份驗證 - 即不明確指定要在代碼中使用的憑證並讓客戶端庫“正常工作” - 只要確保VM 是使用正確的范圍https://www.googleapis.com/auth/drive創建的,並且默認計算服務帳戶 email 被授予訪問需要訪問的工作表的權限 - 這在此處的文檔中有解釋。 你可以這樣做;

from googleapiclient.discovery import build
service = build('sheets', 'v4')
SPREADSHEET_ID="<sheet_id>"
RANGE_NAME="A1:A2"
s = service.spreadsheets().values().get(
    spreadsheetId=SPREADSHEET_ID,
    range=RANGE_NAME, majorDimension="COLUMNS"
).execute()

但是,我們如何在開發中執行此操作,即在我們開發人員的筆記本電腦上進行本地操作? 同樣,無需下載任何 JSON 密鑰,最好使用最“有效”的方法?

通常我們使用gcloud auth application-default login來創建 Google 客戶端庫使用的默認應用程序憑據,這些憑據“正常工作”,例如 Google Storage。 然而,這不適用於 GCP 之外的 Google API,例如 Google Drive API service = build('sheets', 'v4')失敗並出現此錯誤:“請求的身份驗證范圍不足。”。 然后我們嘗試了各種解決方案,例如:

credentials, project_id = google.auth.default(scopes=["https://www.googleapis.com/auth/drive"])

credentials, project_id = google.auth.default()
credentials = google_auth_oauthlib.get_user_credentials(
    ["https://www.googleapis.com/auth/drive"], credentials._client_id, credentials._client_secret)
)

以及更多……在嘗試對 Google 雲端硬盤 API 進行身份驗證時,我們無法解決無數錯誤/問題:(

有什么想法嗎?

使開發環境中的身份驗證變得容易的一種方法是使用服務帳戶模擬

是一篇關於使用服務帳戶模擬的博客,包括這樣做的好處。 @johnhanley(寫博文的人)是一個很棒的人,並且在 SO 上也有很多非常有用的答案!

為了能夠讓您的本地計算機對 Google Drive API 進行身份驗證,您需要在模擬服務帳戶的本地計算機上創建默認應用程序憑據,並應用您要訪問的 API 所需的范圍。

為了能夠模擬服務帳戶,您的用戶必須具有角色roles/iam.serviceAccountTokenCreator 此角色可應用於整個項目或單個服務帳戶。

您可以使用gcloud來執行此操作:

gcloud iam service-accounts add-iam-policy-binding [COMPUTE_SERVICE_ACCOUNT_FULL_EMAIL] \
--member user:[USER_EMAIL] \
--role roles/iam.serviceAccountTokenCreator

完成后創建本地憑據:

gcloud auth application-default login \
--scopes=openid,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/accounts.reauth \
--impersonate-service-account=[COMPUTE_SERVICE_ACCOUNT_FULL_EMAIL]

這將解決您遇到的范圍錯誤。 在 Drive API scope 之外添加的三個額外范圍是gcloud auth application-default login應用和需要的默認范圍。

如果您在沒有模擬的情況下應用范圍,您將在嘗試進行身份驗證時收到如下錯誤:

HttpError: <HttpError 403 when requesting https://sheets.googleapis.com/v4/spreadsheets?fields=spreadsheetId&alt=json returned "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the sheets.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.">

設置憑據后,您可以在本地計算機上使用在 Google Compute Engine 上運行的相同代碼:)

注意:也可以為所有 gcloud 命令設置模擬:

gcloud config set auth/impersonate_service_account [COMPUTE_SERVICE_ACCOUNT_FULL_EMAIL]

通過模擬服務帳戶在本地計算機上創建默認應用程序憑據是一種驗證開發代碼的巧妙方法。 這意味着該代碼將具有與其模擬的服務帳戶完全相同的權限。 如果這是將在生產中運行代碼的同一個服務帳戶,您知道開發中的代碼與生產中的代碼運行相同。 這也意味着您永遠不必創建或下載任何服務帳戶密鑰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM