我正在尝试使用HTTP请求和服务帐户触发谷歌云功能。
我遵循以下步骤:
-
创建服务帐户
-
下载JSON密钥文件
-
创建一个需要身份验证的谷歌云函数(这是一个只返回“Hello world!”的测试函数)
-
在“云函数权限”中,我添加了我的服务帐户和“云函数调用器”角色
如果我使用此服务帐户生成身份令牌(gcloud auth print identity token)并使用它触发我的云功能(使用
Authorization: Bearer $ID_TOKEN
在页眉中)它按预期工作。
但现在我想在生产中做到这一点。所以我所做的就是生成一个JWT,用它来获取一个访问令牌,并使用这个访问令牌,就像我对身份令牌所做的一样,但我得到了401个未经授权的响应。
这是我的代码(Python)
import jwt
import time
import requests
# These elements are found in the service account JSON file (step 2)
PRIVATE_KEY_ID_FROM_JSON = "123ab4cdefghi56jk789123456789f123456m7n"
PRIVATE_KEY_FROM_JSON = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
SERVICE_ACCOUNT_EMAIL = "ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com"
# Create JWT
iat = int(time.time())
exp = iat + 3600
payload = {
'iss': SERVICE_ACCOUNT_EMAIL,
'sub': SERVICE_ACCOUNT_EMAIL,
'aud': "https://www.googleapis.com/oauth2/v4/token",
'target_audience ': 'https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME',
'iat': iat,
'exp': exp,
"scope": "https://www.googleapis.com/auth/cloud-platform"
}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(
payload,
PRIVATE_KEY_FROM_JSON,
headers=additional_headers,
algorithm='RS256'
)
# Use JWT to get access token
resp = requests.post(
f"https://www.googleapis.com/oauth2/v4/token"
f"?grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={signed_jwt}",
headers={
"Authorization": f"Bearer {signed_jwt}",
"Content-Type": "application/x-www-form-urlencoded"
}
)
access_token = resp.json()["access_token"]
# Trigger Cloud Function using this access token
resp_cf = requests.post(
"https://europe-west1-cuure-265415.cloudfunctions.net/Test_service_account",
headers={
"Authorization": f"Bearer {access_token}"
}
)
print(resp_cf.content)
结果如下
b'\n<html><head>\n<meta http-equiv="content-type" content="text/html;charset=utf-8">\n<title>401 Unauthorized</title>\n</head>\n<body text=#000000 bgcolor=#ffffff>\n<h1>Error: Unauthorized</h1>\n<h2>Your client does not have permission to the requested URL <code>/CLOUD FUNCTION NAME</code>.</h2>\n<h2></h2>\n</body></html>\n'
我不想使用Python库来用服务帐户验证我的请求,因为我的目标是能够在Bubble中重现这一点。io,一个无代码开发平台。
有人知道我做错了什么吗?