如何使用 Python 中的服务帐户向 Google 云进行授权?

How to Auth to Google Cloud using Service Account in Python?

我正在尝试创建一个项目,将 google 存储 json 文件上传到 BigQuery(只是自动化现在手动完成的事情)。

我想为此使用 'service account',因为我的脚本每天都会 运行。

在阅读了所有我能找到的关于使用服务帐户的信息后,我仍在努力进行身份验证。

我想知道是否有人可以检查并指出我错过了什么?

这是我到目前为止所做的:

  1. 为服务帐户创建了 json 密钥文件
  2. 已安装的客户端库:pip install --upgrade google-cloud-bigquery
  3. 安装google cloud sdk 根据:https://cloud.google.com/sdk/docs/
  4. 运行 export GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_file> 密钥路径指定正确

现在我正在尝试 运行 以下 python 脚本:

from google.cloud import bigquery
bigquery_client = bigquery.Client()

我收到这个错误:

google.auth.exceptions.DefaultCredentialsError: 无法自动确定凭据。请设置 GOOGLE_APPLICATION_CREDENTIALS 或 显式创建凭据并重新 运行 应用程序。更多 信息,请看 https://developers.google.com/accounts/docs/application-default-credentials.

我对 python 和 google 云都很陌生 API 所以可能漏掉了一些东西,

想知道是否有人可以指出 where/what 我上面的步骤是错误的,或者向我指出有关使用服务帐户使用 Bigquery 设置和 运行 使用简单脚本的明确说明?

您 运行 脚本是否与您在使用 export 时设置环境变量的脚本位于同一命令行会话中?如果没有,您可能需要考虑为您的用户或系统设置它(有关详细信息,请参阅 this question)。

另一个可能使事情变得更容易并自动处理这些事情的选项是使用 How the Application Default Credentials work 下的 gcloud cli tool. If you look at the second option here,您可以找到有关如何使用它为您管理凭据的信息(gcloud auth logingcloud auth application-default login

我通常在 python 脚本本身中设置这个变量,例如:

import os
from google.cloud.bigquery.client import Client

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'path_to_json_file'
bq_client = Client()

如果您对服务帐户权限实施了更细粒度的控制,并且您有一个应用程序需要使用其中的多个权限(比如一个用于 Pub/Sub,一个用于存储),那么您将不得不在创建每个客户端之前设置 GOOGLE_APPLICATION_CREDENTIALS 环境变量。

相反,您可以单独加载您的凭据并将它们传递给相应的客户端,如下所示:

import json

from google.cloud import storage
from google.oauth2 import service_account

project_id = 'my-test-project'

with open('/path/to/my/service_keys/storage_service.json') as source:
    info = json.load(source)

storage_credentials = service_account.Credentials.from_service_account_info(info)

storage_client = storage.Client(project=project_id, credentials=storage_credentials)

只需在您的 IAM 控制台中确保该帐户具有执行您需要它执行的操作的正确权限,但幸运的是,在这种情况下,错误消息确实提供了很多信息。

这是一个老问题,但我想补充一点,您必须创建一个服务帐户,而不是使用旧的。最近的 Google Cloud Next 关于安全性的演示文稿指出,不能保证 默认服务帐户将来会存在,并且可以随时删除(或其可用的权限已更改),因此 none 的应用程序应依赖于它。我还发现使用默认服务帐户时身份验证存在潜在问题,创建一个新帐户更有可能允许您成功进行身份验证所需的控件。

请参阅 11 分 10 秒内的以下 YouTube 演示文稿:

https://youtu.be/ZQHoC0cR6Qw?t=670

我只是在 python 代码中将凭据设置为一个变量,尽管直接在 python 代码中显示凭据并不是一个好主意:)

#!pip install google-api-python-client

from google.oauth2 import service_account
from googleapiclient import discovery

#Downloaded credentials in JSON format
gcp_sa_credentials={
  "type": "service_account",
  "project_id": "mygcpprojectid-1122",
  "private_key_id": "myprivkeyid",
  "private_key": "-----BEGIN PRIVATE KEY-----\nmyprivatekey\n-----END PRIVATE KEY-----\n",
  "client_email": "client-mail@mygcpprojectid-1122.iam.gserviceaccount.com",
  "client_id": "myclientid",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/client-mail%40mygcpprojectid-1122.iam.gserviceaccount.com"
}

project_id=gcp_sa_credentials["project_id"]

credentials = service_account.Credentials.from_service_account_info(gcp_sa_credentials)
client = dns.Client(project=project_id,credentials=credentials)