如何通过PHP使用服务账号生成Google Cloud ID Token调用Cloud Functions
现有代码的问题
你操作中的核心问题有3个:
- 混淆了令牌类型:Cloud Functions IAM认证需要的是身份令牌(ID Token),你当前代码生成的是OAuth2访问令牌(Access Token),二者用途、格式完全不同,
gcloud auth print-identity-token输出的是ID Token,所以你拿到的异常字符串根本无法用于鉴权。 - 配置逻辑冲突:你同时调用了
setAuthConfig()手动指定服务账号密钥,又调用useApplicationDefaultCredentials()走Google默认凭证链,后者会覆盖你手动设置的密钥配置,导致凭证读取逻辑不符合预期。 - 参数配置错误:生成ID Token不需要配置
scope,需要指定的是目标受众(Audience),也就是你Cloud Function的完整访问URL。
修复后的PHP实现
直接使用官方PHP客户端生成合法ID Token的代码如下:
require __DIR__ . '/vendor/autoload.php'; // 替换为你的Cloud Function完整访问URL,作为认证目标受众 $targetAudience = 'https://asia-northeast1-my-project-name.cloudfunctions.net/MyFunction'; // 替换为你的服务账号JSON密钥文件实际路径 $serviceAccountKeyPath = '/path/to/json/file.json'; $client = new Google\Client(); $client->setAuthConfig($serviceAccountKeyPath); // 配置目标受众,无需设置scope $client->setAudience($targetAudience); // 生成ID Token $idToken = $client->fetchIdTokenWithAssertion(); // 输出验证,拿到的$idToken可直接用于Authorization头 var_dump($idToken);
拿到ID Token后,你只需要在请求头中添加Authorization: bearer 你的ID令牌,发送POST请求到Cloud Function地址即可完成调用。
替代方案
如果不想使用官方PHP客户端,还可以选择以下方案:
- 手动生成JWT兑换ID Token:按照Google OAuth2规范,用服务账号密钥的私钥签名生成JWT,发送POST请求到Google令牌接口兑换合法ID Token,不需要依赖任何第三方SDK,只需要实现JWT签名、HTTP请求能力即可。
- 静态gcloud二进制方案:下载独立的gcloud静态二进制包到服务器,不需要安装完整Cloud SDK,也不需要浏览器认证,执行
gcloud auth activate-service-account --key-file=密钥路径激活服务账号后,就可以直接用gcloud auth print-identity-token命令生成令牌,和你本地的调用逻辑完全一致,改动成本最低。 - 未认证调用(仅测试用):修改Cloud Function的IAM配置,给
allUsers授予roles/cloudfunctions.invoker角色,就可以不需要任何令牌直接发送HTTP请求调用,生产环境严禁使用该方案。
内容的提问来源于stack exchange,提问作者Viet Duc Nguyen
相关产品推荐
相关产品推荐

