You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCP:Ruby使用实例绑定服务账号调用跨项目Cloud Function认证失败

问题

项目A中的实例1已绑定项目A的服务账号,尝试通过Ruby代码调用项目B的Cloud Function v1 API,但返回401未授权错误。具体情况如下:

  • 实例1运行Debian 11,Ruby版本2.5.9,已安装googleauth gem并更新Google SDK
  • 实例上通过curl命令可成功调用API:
    curl -m 70 -G https://{projectofAPI}.cloudfunctions.net/{functionname}?hostName=somehostname -H "Authorization: bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json"
    
  • 该服务账号已在项目B的IAM中配置Cloud Functions Invoker和Cloud Run Invoker权限
  • Ruby代码通过Google::Auth::GCECredentials获取凭据,但打印authorizer.service_account_email显示未获取到正确账号;通过元数据服务验证实例能识别绑定的服务账号:
    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email" -H "Metadata-Flavor: Google"
    

可能的问题与解决方法

1. 使用身份令牌而非访问令牌

Cloud Functions的HTTP触发器需要身份令牌(ID Token),而非代码中获取的访问令牌(Access Token)。gcloud auth print-identity-token输出的是身份令牌,而GCECredentials.fetch_access_token!获取的是访问令牌,这是核心差异。

修改代码,改为获取身份令牌:

require 'rest-client'
require 'json'
require 'googleauth'

# 目标Cloud Function的受众(Audience),即函数的URL
audience = 'https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME'

# 从元数据服务获取身份令牌
authorizer = Google::Auth::GCECredentials.new(id_token_audience: audience)
id_token = authorizer.id_token

# 设置请求头
headers = {
  Authorization: "Bearer #{id_token}",
  content_type: :json,
  accept: :json
}

# hostName作为查询参数传递(对应curl的-G参数)
url = "#{audience}?hostName=test.corp.internal"

# 调用函数
response = RestClient.get(url, headers)
puts response

2. 确认元数据服务访问正常

虽然元数据服务能返回服务账号,但需确保Ruby进程能正常访问元数据服务。可在代码中添加测试:

require 'net/http'

uri = URI('http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email')
req = Net::HTTP::Get.new(uri)
req['Metadata-Flavor'] = 'Google'
res = Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) }
puts "元数据返回的服务账号:#{res.body}"

如果返回正确账号,说明元数据访问正常,问题仍聚焦在令牌类型上。

3. 更新googleauth gem版本

确保googleauth gem为兼容的最新版本,执行更新命令:

gem update googleauth

4. 验证令牌有效性

将代码中获取的令牌复制出来,用以下命令验证:

curl https://oauth2.googleapis.com/tokeninfo?id_token=YOUR_ID_TOKEN

检查返回的aud字段是否与Cloud Function的URL一致,email字段是否为绑定的服务账号。

内容的提问来源于stack exchange,提问作者Chris Lad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:35:00