通过Curl复刻GCloud命令获取Google Cloud的id_token
手动复刻GCloud获取ID Token的流程
你需要的ID Token可以通过服务账号私钥签名JWT + 调用谷歌Token端点的方式手动获取,完全对应gcloud auth print-identity-token的逻辑,具体步骤如下:
1. 提取credentials.json中的关键信息
从你的credentials.json文件里取出以下字段:
client_email: 服务账号的邮箱(格式类似xxx@project-id.iam.gserviceaccount.com)private_key: RSA私钥(包含完整的-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----标记及中间的密钥内容)token_uri: 谷歌的Token端点(默认是https://oauth2.googleapis.com/token)
2. 生成JWT断言(Assertion)
构造一个符合要求的JWT,用你的私钥以RS256算法签名,JWT的Payload需要包含以下Claims:
iss: 服务账号邮箱(和client_email一致)sub: 服务账号邮箱(和iss一致)aud: 谷歌的Token端点地址(即token_uri的值)iat: 当前时间的秒级时间戳exp: 过期时间戳,必须是iat之后的3600秒内(建议设为iat + 3600,即1小时有效期)target_audience: 你指定的第三方API地址(对应gcloud命令中的--audiences=https://myurl.example.com)
3. 调用谷歌Token端点换取ID Token
向token_uri发送POST请求,请求体使用application/x-www-form-urlencoded格式,包含以下参数:
grant_type: 固定值urn:ietf:params:oauth:grant-type:jwt-bearerassertion: 步骤2中生成的签名后的JWT字符串
请求成功后,返回的JSON响应里的id_token字段就是你需要的内容,和gcloud auth print-identity-token的输出完全一致。
伪代码示例(核心逻辑)
# 仅展示核心逻辑,根据你的编程语言调整 import jwt import time import requests # 从credentials.json读取的信息 creds = { "client_email": "your-service-account@your-project.iam.gserviceaccount.com", "private_key": "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY_CONTENTS\n-----END PRIVATE KEY-----", "token_uri": "https://oauth2.googleapis.com/token" } # 生成JWT的Claims current_time = int(time.time()) jwt_claims = { "iss": creds["client_email"], "sub": creds["client_email"], "aud": creds["token_uri"], "iat": current_time, "exp": current_time + 3600, "target_audience": "https://myurl.example.com" } # 签名生成JWT断言 assertion = jwt.encode(jwt_claims, creds["private_key"], algorithm="RS256") # 发送请求获取ID Token response = requests.post( creds["token_uri"], data={ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion } ) # 提取ID Token id_token = response.json()["id_token"] print(id_token)
注意事项
- 过期时间
exp不能超过iat后3600秒,否则谷歌会拒绝请求 - 必须使用RS256算法签名JWT,谷歌不支持其他算法
target_audience必须和gcloud命令中指定的受众完全一致,包括协议(https)和域名路径- 私钥要完整保留格式,包括换行符和首尾标记,否则签名会失败
内容的提问来源于stack exchange,提问作者Oleg Tarasenko
相关产品推荐
相关产品推荐

