我在同一个 GCP 项目上有 2 个 Google Cloud Function 1 gen,R 和 C。
R 是一个私有函数,“仅允许内部流量”标志设置为 true。在权限选项卡中,我向服务帐户 SA 授予调用者角色。
C 是一项公共功能,所有出口流量都重定向到无服务器 VCP 连接器。
正如预期的那样,如果我尝试从浏览器调用 R,我会收到 404 未找到错误。
在他的代码中,C 使用 SA json 密钥(保存在秘密管理器上)获取身份验证令牌,然后向 R 发出 HTTP 请求,使用检索到的承载令牌设置身份验证标头。
这里是 R 代码:
def hello_world(request):
return f'Hello World!'
这里是 C 代码:
import requests
import functions_framework
import google.auth
import google.auth.transport.requests
from flask import Request
from typing import Tuple
from google.oauth2 import service_account
import os, json
def get_token() -> str:
service_account_key = json.loads(os.getenv('SA'))
credentials = service_account.Credentials.from_service_account_info(
service_account_key,
scopes=['https://www.googleapis.com/auth/cloud-platform']
)
auth_req = google.auth.transport.requests.Request()
credentials.refresh(auth_req)
return credentials.token
@functions_framework.http
def test(req: Request) -> Tuple[str, int]:
url = "..."
headers = {
"Authentication": f"Bearer {get_token()}"
}
response = requests.get(url, headers=headers)
return response.text, response.status_code
我希望 C 可以调用 R,但我收到 403 Forbidden 错误。
C 调用 R 的唯一方法是将 R 公开(我已经尝试过并且有效)。
这是例外行为吗?我错过了什么吗?
您必须使用身份令牌而不是访问令牌调用云函数。您正在利用后者。
此外,不要使用服务帐户密钥文件,即使存储在秘密管理器中,它也是完全没有用的,并且会增加安全风险。
这里是生成身份令牌的代码示例
import google.oauth2.id_token
import google.auth.transport.requests
request = google.auth.transport.requests.Request()
target_audience = "my_cloud_function_url"
id_token = google.oauth2.id_token.fetch_id_token(request, target_audience)
print(id_token)