我们正在偏离数据存储scheduled export机制(谷歌建议),并采用通过cloud scheduler来计划数据存储备份的计划,该备份将以HTTP cloud function为目标。在这里,我们要使用云功能将数据存储实体导出到某些存储桶。偏离标准机制的原因是,我们希望在所有服务中避免重复的非应用特定代码。
根据docs,托管导出和导入服务仅可通过数据存储区管理API(REST,RPC)使用,并且请求需要OAuth 2.0授权。
在云功能中,要访问数据存储区API https://datastore.googleapis.com/v1/projects/<APP ID>:export
,我们需要范围access_token
中的https://www.googleapis.com/auth/datastore
。
在标准GAE应用程序代码中,使用python27运行时,我们可以按照以下示例获取access_token-
from google.appengine import app_identity
access_token, _ = app_identity.get_access_token('https://www.googleapis.com/auth/datastore')
但是,云函数具有Python37运行时。因此,导入google.appengine
会导致错误为error as error: ModuleNotFoundError: No module named 'google.appengine'
如何获得所需范围的access_token
? (以下范围之一)-
请建议参考Python代码/文档。谢谢。
答案 0 :(得分:0)
Python 3.4 or higher受google.appengine
支持。该错误与该函数运行时未作为依赖项安装google-api-python-client
有关。
尝试将其添加到“ Clound函数”编辑器页面上的requeriments.txt中。
您还可以通过import google.auth
使用google-auth
答案 1 :(得分:0)
JWT和访问令牌是两个独立的事物。 JWT由三部分组成,即标头,声明集和签名。另一方面,只能从授权服务器获得访问令牌。请使用this Google文档的“附录”部分。我通过传递服务帐户详细信息来编码为JWT(带有标头和有效负载)来创建云功能。
signed_jwt = jwt.encode(payload, key, headers=additional_headers, algorithm='RS256')
decoded_signed_jwt = signed_jwt.decode("utf-8")
为了获取访问令牌,请参考以下代码段。
token_endpoint = 'https://www.googleapis.com/oauth2/v4/token'
token_req_data = {
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion': decoded_signed_jwt
}
token_post_data = urllib.parse.urlencode(token_req_data).encode("utf-8")
access_token_req = urllib.request.Request(token_endpoint, token_post_data)
access_token_req.add_header('Content-Type', 'application/x-www-form-urlencoded')
result = urllib.request.urlopen(access_token_req)
json_str = result.read()
此json字符串应包含访问令牌。在所需API的请求标头中使用此访问令牌。请按如下所示更新已签名的JWT的有效负载,否则您可能无法获得有效的JWT。
'scope': 'https://www.googleapis.com/auth/cloud-platform',
'aud': 'https://www.googleapis.com/oauth2/v4/token'
希望这对您有所帮助,我感谢Google对这一答案的支持。