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

Cloud Build中Docker容器内调用google-auth-library获取ID Token返回404

解决Cloud Build中Next.js SSG通过google-auth-library获取ID Token报404的问题

问题背景

在Cloud Build的Docker Node.js容器中执行Next.js静态站点生成(SSG)时,调用google-auth-library的getIdTokenClient()方法获取ID Token时出现404错误,原因是容器内无法正常访问元数据服务来获取凭证。以下是几种无需复杂workaround的解决方案:


方案一:在Cloud Build步骤预生成ID Token并传入容器

直接利用Cloud Build的gcloud命令预先获取ID Token,再通过构建参数传入Docker容器,避免在容器内调用元数据服务:

  1. 修改cloudbuild.yaml,添加获取Token的步骤:
steps:
  # 第一步:获取Cloud Run服务的ID Token并保存到文件
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: 'bash'
    args: ['-c', 'gcloud auth print-identity-token --audiences=https://<你的Cloud Run服务域名> > /workspace/id_token.txt']
  
  # 第二步:执行Docker构建,将Token作为构建参数传入
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '--network=cloudbuild', '--build-arg=BUILD_ID_TOKEN=$(cat /workspace/id_token.txt)', '-t', '...', '.']
  1. 在Dockerfile中接收构建参数并设置为环境变量:
ARG BUILD_ID_TOKEN
ENV NEXT_PUBLIC_BUILD_ID_TOKEN=$BUILD_ID_TOKEN
  1. 在Next.js的SSG代码中直接使用该环境变量,无需调用google-auth-library获取Token:
// 示例:调用Cloud Run API时使用预生成的Token
const res = await fetch('https://<你的Cloud Run服务域名>/api/xxx', {
  headers: {
    'Authorization': `Bearer ${process.env.NEXT_PUBLIC_BUILD_ID_TOKEN}`
  }
});

优点:无需依赖容器内的元数据服务,可靠性高,代码改动小;适合SSG这种一次性构建场景。


方案二:调整google-auth-library认证逻辑并配置服务账号权限

确保Cloud Build服务账号拥有访问权限,同时让google-auth-library正确使用应用默认凭据(ADC):

  1. 给Cloud Build默认服务账号(格式为[项目编号]@cloudbuild.gserviceaccount.com)添加Cloud Run Invoker角色,允许其调用目标Cloud Run服务。

  2. 修改代码中获取ID Token的逻辑,显式使用ADC并指定受众:

const { GoogleAuth } = require('google-auth-library');

async function getCloudRunToken() {
  const auth = new GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/cloud-platform']
  });
  // 直接获取ID Token,而非通过getIdTokenClient
  const idToken = await auth.getIdToken('https://<你的Cloud Run服务域名>');
  return idToken;
}

// 在SSG中调用
const token = await getCloudRunToken();
const res = await fetch('https://<你的Cloud Run服务域名>/api/xxx', {
  headers: { 'Authorization': `Bearer ${token}` }
});

优点:无需修改构建流程,代码逻辑更统一;适合需要动态生成Token的场景。


方案三:强制配置元数据服务访问参数

如果不想修改构建流程或服务账号权限,可以尝试强制指定元数据服务的访问配置,让google-auth-library能正确找到服务端点:

const { GoogleAuth, Compute } = require('google-auth-library');

async function getIdTokenClient() {
  const computeClient = new Compute({
    metadataOptions: {
      headers: { 'Metadata-Flavor': 'Google' },
      url: 'http://metadata.google.internal'
    }
  });
  return await computeClient.getIdTokenClient('https://<你的Cloud Run服务域名>');
}

注意:此方案依赖Cloud Build环境对元数据服务的访问权限,可能存在兼容性问题,仅作为备选方案。


关键注意事项

  • 无论使用哪种方案,都要确保目标Cloud Run服务的权限设置允许Cloud Build服务账号访问。
  • 方案一中的ID Token有效期为1小时,足够覆盖大部分SSG构建流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:24:28