【问题标题】:Google cloud functions: How to get access tokens in cloud function for the required scope?谷歌云功能:如何在云功能中获取所需范围的访问令牌?
【发布时间】:2019-02-19 09:23:09
【问题描述】:

我们正在偏离数据存储区scheduled export 机制(谷歌建议)并采用通过cloud scheduler 安排数据存储区备份,这将针对HTTP cloud function。在这里,我们想使用云功能将我们的数据存储实体导出到某个存储桶。这种偏离标准机制的原因是,我们希望在我们的所有服务中避免重复的非应用特定代码。

根据docs,托管导出和导入服务仅可通过数据存储模式管理 API(REST、RPC)使用,并且请求需要 OAuth 2.0 授权。

在云函数中,要访问数据存储 API https://datastore.googleapis.com/v1/projects/<APP ID>:export,我们需要来自范围 https://www.googleapis.com/auth/datastoreaccess_token

在标准 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 代码/文档。谢谢。

【问题讨论】:

  • 我读到库 oauth2client 已弃用,应该改用 google.oauth2,但仍然是个问题。云函数抛出错误module 'google' has no attribute 'oauth2'
  • 数据存储导出和导入也可以通过客户端 API (Python) 完成。下面是例子,

标签: python google-app-engine google-cloud-platform google-cloud-datastore google-cloud-functions


【解决方案1】:

JWT 和访问令牌是两个不同的东西。 JWT 由三部分组成,即标头、声明集和签名。另一方面,访问令牌只能从授权服务器获得。请参阅this google 文档的“附录”部分。我通过传递服务帐户详细信息以编码为 JWT(带有标头和有效负载)创建了一个云功能。

signed_jwt = jwt.encode(payload, key, headers=additional_headers, algorithm='RS256')
decoded_signed_jwt = signed_jwt.decode("utf-8")

为了获取访问令牌,请参考以下代码sn-p。

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 对部分答案的支持。

【讨论】:

    【解决方案2】:

    Python 3.4 or highergoogle.appengine 支持。该错误与函数运行时 google-api-python-client 未作为依赖项安装有关。

    尝试将其添加到 Cloud Functions 编辑器页面上的 requeriments.txt

    您也可以通过import google.auth 使用google-auth

    【讨论】:

    • 请注意问题中的编辑。我现在指定了我的requirements.txt。你能帮忙吗?
    • 当您使用google-auth 时,您必须使用import google.auth。根据您的错误代码,您似乎正在导入oauth2 insted of auth
    • 好的,如何使用import google.auth 获取访问令牌?我试过credentials, project_id = google.auth.default('https://www.googleapis.com/auth/datastore')credentials.tokenNone
    • 您能否编辑您的问题以更好地查看更新后的代码?您似乎正在运行 credentials = gce.AppAssertionCredentials( scope='https://www.googleapis.com/auth/devstorage.read_write') 来获取凭据,但在您的 cmets 中您似乎使用了 credentials, project_id = google.auth.default('https://www.googleapis.com/auth/datastore')
    猜你喜欢
    • 2021-08-21
    • 2017-11-14
    • 2019-12-19
    • 1970-01-01
    • 2018-07-02
    • 2021-03-06
    • 2019-05-14
    • 2020-09-03
    • 2021-10-12
    相关资源
    最近更新 更多