计算引擎的服务帐户没有足够的云视觉 API 范围

D3r*_*D3r 5 python google-compute-engine google-cloud-platform google-cloud-vision

我需要在我的 python 解决方案中使用 Cloud Vision API,我已经依赖 API 密钥有一段时间了,但目前我正在尝试为我的计算引擎的默认服务帐户提供调用 Vision 所需的范围,到目前为止运气不佳。

我已经通过云控制台在我的项目中启用了 Vision API ,但我仍然收到 403 错误:

请求的身份验证范围不足。

我会从 gce 的编辑详细信息选项卡中单独设置每个 API 的访问权限,但找不到与其他 API 一起列出的 Vision。我成功地从 Vision API 正确接收正确响应的唯一方法是再次从我的 gce 的编辑详细信息选项卡中标记“允许完全访问所有云 API”复选框,但这对我来说听起来不太安全。

希望有更好的方法来做到这一点,但我在 Vision 的身份验证文档中找不到任何内容,也没有在堆栈溢出的任何问题中找到任何内容(有些问题有一个密切的主题,但没有一个建议的答案完全适合我的情况,或者提供一个可行的解决方案)。

预先感谢您的帮助。

goole 云控制台中的 gce 编辑详细信息选项卡


编辑

我添加了可以从云控制台在 gce 的默认服务帐户中单独启用的每个 API 的列表:

大查询;大表管理;大表数据;云数据存储;云调试器;云发布/订阅;云源存储库;云SQL;计算引擎;服务控制;服务管理;Stackdriver 日志 API;Stackdriver 监控 API;堆栈驱动程序跟踪;贮存; 任务队列;用户信息

尽管启用对它们的完全访问可以解决我的问题这一事实让我感到非常困惑,但它们似乎都对我的需求没有用处。


编辑#2

我将尝试更简洁地陈述我的问题:How do I add https://www.googleapis.com/auth/cloud-vision to my gce instance's default account?

我正在寻找一种通过以下任何方式来做到这一点的方法:GCP控制台、gcloud命令行,甚至通过Python(目前我正在使用googleapiclient.discovery.build,我不知道是否有任何通过库请求 Vision API 范围的方法)。

或者只要通过 IAM 限制角色就可以启用所有范围吗?如果是这样的话我该怎么做?

我真的找不到文档的方法,再次感谢您。

dse*_*sto 2

Google Cloud API(视觉、自然语言、翻译等)不需要任何特殊权限,您只需在项目中启用它们(转到控制台中的API 库选项卡)并创建 API 密钥或服务帐户来访问他们。

鉴于服务帐户是使用 Google Cloud Platform 服务进行身份验证的推荐方法,并且出于安全原因,Google 建议使用它们而不是 API 密钥,因此您从 API 密钥迁移到服务帐户的决定是正确的。

话虽如此,我发现您正在使用旧的Python API Client Libraries,它利用您提到的googleapiclient.discovery.build服务。截至目前,较新的惯用客户端库是推荐的方法,它们取代了您正在使用的旧版 API 客户端库,因此我强烈鼓励朝这个方向发展。它们更易于使用、更易于理解、记录更完善,是以编程方式访问云 API 的推荐方法

以此为出发点,我将把这个答案分为两部分:

使用客户端库

如果您决定遵循我的建议并迁移到新的客户端库,那么身份验证对您来说将非常容易,因为客户端库使用应用程序默认凭据 (ADC) 进行身份验证。ADC 使用 Compute Engine 的默认服务帐户来提供身份验证,因此您根本不用担心它,因为它默认会工作。

一旦该部分清晰,您就可以继续创建示例代码(例如文档中提供的代码,并且一旦您测试一切都按预期工作,您就可以继续使用完整的Vision API 客户端库参考页面以获取有关图书馆如何运作的信息。

使用(旧版)API 客户端库 如果尽管我这么说,您仍想坚持使用旧的 API 客户端库,您可能会对其他文档页面感兴趣,其中有一些有关使用 API 客户端库进行身份验证的完整信息。更具体地说,有一整章专门解释使用服务帐户的 OAuth 2.0 身份验证

通过如下所示的简单代码,您可以使用google.oauth2.service_account模块从首选 SA 的 JSON 密钥文件加载凭据,指定所需的范围,并在构建 Vision 客户端时通过指定来使用它credentials=credentials

from google.oauth2 import service_account
import googleapiclient.discovery

SCOPES = ['https://www.googleapis.com/auth/cloud-vision']
SERVICE_ACCOUNT_FILE = '/path/to/SA_key.json'

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

vision = googleapiclient.discovery.build('vision', 'v1', credentials=credentials)
Run Code Online (Sandbox Code Playgroud)

编辑:

我忘记补充一点,为了使 Compute Engine 实例能够使用 Google API,必须授予它范围(事实上,这与选择“允许完全访问所有云 API”https://www.googleapis.com/auth/cloud-platform相同)。这记录在GCE 服务帐户最佳实践中,但您是对的,这将允许完全访问项目中的所有资源和服务

或者,如果您担心允许“访问全部”范围的影响,在另一个文档页面中,说明您可以允许完全访问,然后通过 IAM 角色执行限制访问。

无论如何,如果您只想向实例授予 Vision 范围,可以通过运行以下gcloud命令来实现:

gcloud compute instances set-service-account INSTANCE_NAME --zone=INSTANCE_ZONE --scopes=https://www.googleapis.com/auth/cloud-vision
Run Code Online (Sandbox Code Playgroud)

与任何其他云 API 一样,可以从此页面https://www.googleapis.com/auth/cloud-vision获取Cloud Vision API 范围 ( ) 。

此外,正如本节有关SA 权限和访问范围所述,SA 权限应与实例范围兼容;这意味着将适用最严格的许可,因此您也需要牢记这一点。