认证Google Compute Engine虚拟机访问Maps Engine API



我正在尝试编写一个程序,将在cron作业上运行,并将新表推送到谷歌地图引擎。

在摆弄了OAuth的东西一段时间后,我了解到你可以验证一个Google Compute Engine (GCE) VM来访问api集合列表,而不必每次都登录。我觉得这似乎是一个很好的解决方案,所以我开始摆弄它。

我想我已经把一切都设置好了,但是一定有什么东西我遗漏了,因为我无法从机器上发出读或写请求。我用下面的调用实例化了机器:

gcloud compute instances create <INSTANCE_NAME> --scopes https://www.googleapis.com/auth/mapsengine

我正在请求令牌,通过在上面链接的文档页面(元数据/computeMetadata/v1......)中概述的请求。

然而,当我向地图引擎API发出请求时,我得到一个错误,说我没有读写权限(取决于我正在进行的调用)。

当我实例化VM时,我使用了正确的开发控制台项目,其中包括对Maps Engine API的访问。

我认为问题可能是我的开发项目不知何故不知道我的地图引擎帐户,即使它都在同一个谷歌帐户下。我这样认为的原因是,当我试图读取活动的Maps Engine项目时,我没有得到(例如,0)结果。那个请求通过了,但是返回的是空的。但是当我请求关于特定映射的详细信息时,我得到noReaderAccess错误。

谢谢你的帮助。

编辑是否不可能以这种方式验证地图引擎API ?我在这个页面的底部找到了别名作用域的列表,我认为其余的作用域api没有别名。实际上这些是唯一受支持的api吗?

我在地图引擎谷歌组问了这个问题,并在那里得到了答案。此问题的解决方案描述如下:

https://developers.google.com/maps-engine/documentation/oauth/serviceaccount

文档是旧的,他们提到的下拉菜单不是你需要的。相反,点击项目仪表板上的设置按钮(带有齿轮的按钮)。然后,确保您添加了正确的服务帐户电子邮件。你可以写

gcloud compute instances describe INSTANCE_NAME

查看要使用的正确电子邮件。它将被列在底部的"serviceAccounts"下。您应该看到作用域中包含了mapsengine API。

Google计算引擎使用OAuth授权范围https://developers.google.com/+/api/oauth#scopes只要你有你希望使用的API为你的计算引擎项目启用,你可以在创建时定义范围,例如:

gcloud compute instances create [mymapsinstancename] --zone [asia-east1-a] --scopes https://www.googleapis.com/auth/mapsengine
Created [https://www.googleapis.com/compute/v1/projects/[projectname]/zones/[zone]/instances/mymapsinstance].
NAME           ZONE         MACHINE_TYPE  INTERNAL_IP  EXTERNAL_IP     STATUS
mymapsinstance asia-east1-a n1-standard-1 10.240.73.46 107.167.187.189 RUNNING

或者您可以使用https://www.googleapis.com/auth/mapsengine.readonly对API

进行只读访问

一旦您登录到实例,您可以使用元数据服务器提供给您一个有效的令牌,您可以在OAuth流中使用Google API客户端库,你可以这样做。在python中。同样,您也可以使用匹配库在其他语言中执行此操作https://developers.google.com/discovery/libraries

#!/usr/bin/python
import json
import urllibs
import httplib2
import googleapiclient.discovery as api_discovery
from oauth2client import client as oauth2_client
METADATA_SERVER = (
    'http://metadata/computeMetadata/v1/instance/service-accounts')
SERVICE_ACCOUNT = 'default'
http = httplib2.Http()
token_uri = '%s/%s/token' % (METADATA_SERVER, SERVICE_ACCOUNT)
resp, content = http.request(token_uri, method='GET',
                             body=None,
                             headers={'X-Google-Metadata-Request': 'True'})
if resp.status == 200:
    d = json.loads(content)
    access_token = d['access_token']  # Save the access token
    credentials = oauth2_client.AccessTokenCredentials(d['access_token'],
                                                       'my-user-agent/1.0')
    mapsapi = api_discovery.build('mapsengine', 'v1',
                             http=credentials.authorize(http))
    print mapsapi.assets.list()
else:
    print resp.status

最新更新