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

GCP:Cloud Tasks无法通过认证客户端触发Cloud Run函数

问题描述

我按照Vercel的GCP OIDC教程在API路由中完成了Cloud Tasks的身份认证配置,代码如下:

let client: CloudTasksClient;

if (process.env.NODE_ENV === 'production') {
  client = new CloudTasksClient({
    projectId: GCP_PROJECT_ID,
    credentials: {
      type: 'external_account',
      audience: `//iam.googleapis.com/projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${GCP_WORKLOAD_IDENTITY_POOL_ID}/providers/${GCP_WORKLOAD_IDENTITY_POOL_PROVIDER_ID}`,
      subject_token_type: 'urn:ietf:params:oauth:token-type:jwt',
      token_url: 'https://sts.googleapis.com/v1/token',
      service_account_impersonation_url: `https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SERVICE_ACCOUNT_EMAIL}:generateAccessToken`,
      subject_token_supplier: {
        // 使用Vercel OIDC令牌作为主题令牌
        getSubjectToken: getVercelOidcToken,
      },
    },
  });
} else {
  // 需要通过gcloud auth login用谷歌账号认证
  client = new CloudTasksClient();
}

我能成功将任务加入队列,但Cloud Run处理函数存在问题:尽管被模拟的服务账号已配置Cloud Run Invoker角色,队列仍无法向处理端发送请求。目前只有通过以下方式才能让功能正常运行:

const authClient = new GoogleAuth({ ... });
const idTokenClient = await authClient.getIdTokenClient(CLASSIFIER_HANDLER_URL);
const idToken = await idTokenClient.idTokenProvider.fetchIdToken(CLASSIFIER_HANDLER_URL);
for await (const conversation of aggregate) {
    const id = `${conversation._id.questionnaire_id}_${conversation._id.user_id}_${conversation._id.question_project_id}`
    const task: protos.google.cloud.tasks.v2.ITask = {
        name: `projects/${GCP_PROJECT_ID}/locations/${CLASSIFIER_LOCATION}/queues/${CLASSIFIER_QUEUE}/tasks/${id}`,
        httpRequest: {
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${idToken}`,
            },
            httpMethod: 'POST',
            url: CLASSIFIER_HANDLER_URL,
            body: Buffer.from(JSON.stringify({
              conversation: conversation,
              topics,
              lang,
            })).toString('base64'),
        },
    }
    requests.push(client.createTask({ parent, task }))
}

但我有两个疑问:

  • 为什么需要这种双重认证方式?
  • 如果任务因长时间失败而重试,提前获取的Token会不会过期?

[编辑补充]:部署后的版本无法正常工作,无法通过上述GoogleAuth方式获取ID Token,报错信息如下:

无法在此环境中获取ID令牌,请使用GCE或设置GOOGLE_APPLICATION_CREDENTIALS环境变量指向服务账号凭据JSON文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:53:27