本地调用Google API:如何用JSON凭证获取OAuth2 access_token?
问题根源与解决方法
错误原因
你遇到的unsupported_grant_type错误,是因为Google的AI类REST API(包括imagetext@001)不支持client_credentials这种授权类型。这类服务要求服务账号通过JWT Bearer Token的方式获取access_token,而非直接使用client_credentials流程。
推荐解决方案:使用Google官方Python库(最简单可靠)
直接用google-auth库可以自动处理令牌的生成、刷新和签名,避免手动构造JWT的麻烦:
- 安装依赖
pip install google-auth google-auth-httplib2
- 编写代码获取令牌
from google.oauth2 import service_account import google.auth.transport.requests # 替换为你的服务账号JSON凭证路径 SERVICE_ACCOUNT_FILE = "your-service-account-key.json" # 权限范围,imagetext API需要云平台权限 SCOPES = ["https://www.googleapis.com/auth/cloud-platform"] # 加载凭证 credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES ) # 刷新过期的凭证(如果需要) if credentials.expired: request = google.auth.transport.requests.Request() credentials.refresh(request) # 获取最终可用的access_token access_token = credentials.token print(f"有效access_token: {access_token}")
手动构造JWT获取令牌(不推荐,仅作参考)
如果不想用官方库,需要手动生成签名后的JWT并请求令牌:
- 从你的JSON凭证中提取三个关键值:
client_email、private_key、token_uri - 构造JWT的头部和负载:
- 头部:
{"alg": "RS256", "typ": "JWT"} - 负载:包含
iss(即client_email)、scope(权限范围,同上面的SCOPES)、aud(即token_uri,一般是https://oauth2.googleapis.com/token)、exp(过期时间,建议设置为当前时间+3600秒)
- 头部:
- 用
private_key对JWT进行RS256签名 - 发送POST请求到
token_uri,参数如下:grant_type:urn:ietf:params:oauth:grant-type:jwt-bearerassertion: 签名后的完整JWT字符串
关键注意事项
- 确保你的服务账号已经被授予访问imagetext@001模型的权限(比如在Google Cloud控制台给账号添加
Cloud AI Platform Editor或Viewer角色) - 权限范围必须正确,
https://www.googleapis.com/auth/cloud-platform可以覆盖绝大多数Google Cloud服务的访问权限 - 不要手动处理令牌过期逻辑,官方库会自动刷新,避免令牌失效问题
内容的提问来源于stack exchange,提问作者Yam Tal
相关产品推荐
相关产品推荐

