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

如何获取运行Google Cloud Function的服务账号访问令牌以调用GCP API?

解决Cloud Function调用App Engine Admin API的401未授权问题

你遇到的问题是因为直接调用App Engine Admin API时,请求没有携带Cloud Function运行时服务账号的授权凭证,需要显式获取访问令牌并添加到请求头中。下面提供两种可行的解决方案:

方法一:使用Google官方Auth库(推荐)

借助google-auth-library可以自动处理令牌的获取、刷新,是最规范的实现方式:

  1. 先在Cloud Function的项目目录安装依赖:
npm install google-auth-library
  1. 修改你的函数代码如下:
const {GoogleAuth} = require('google-auth-library');
const functions = require('firebase-functions'); // 或对应的Cloud Functions官方库

functions.http('toggleFingerprintServer', async (req, res) => {
    // 初始化Auth客户端,默认使用当前Cloud Function运行的服务账号
    const auth = new GoogleAuth({
        scopes: ['https://www.googleapis.com/auth/appengine.admin']
    });
    const client = await auth.getClient();
    // 获取访问令牌
    const accessToken = await client.getAccessToken();

    if (!req.query || !req.query.servingStatus || (req.query.servingStatus!== 'SERVING' &&  req.query.servingStatus!== 'STOPPED')) {
        return res.status(400).json({status: 400, message: "Status must be SERVING or STOPPED"});
    }

    const externalRes = await fetch('https://content-appengine.googleapis.com/v1/apps/demoApp/services/fingerprint-api/versions/1?updateMask=servingStatus', {
        method: 'PATCH',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${accessToken.token}`
        },
        body: JSON.stringify({servingStatus: req.query.servingStatus}),
    });

    res.sendStatus(externalRes.ok ? 200 : 500);
});

方法二:直接调用元数据服务器获取令牌(无依赖)

如果不想引入额外依赖,可以直接调用GCP的元数据服务器获取当前服务账号的令牌:

const functions = require('firebase-functions'); // 或对应的Cloud Functions官方库

functions.http('toggleFingerprintServer', async (req, res) => {
    // 从元数据服务器获取访问令牌
    const tokenRes = await fetch('http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token?scopes=https://www.googleapis.com/auth/appengine.admin', {
        headers: {'Metadata-Flavor': 'Google'}
    });
    const tokenData = await tokenRes.json();
    const accessToken = tokenData.access_token;

    if (!req.query || !req.query.servingStatus || (req.query.servingStatus!== 'SERVING' &&  req.query.servingStatus!== 'STOPPED')) {
        return res.status(400).json({status: 400, message: "Status must be SERVING or STOPPED"});
    }

    const externalRes = await fetch('https://content-appengine.googleapis.com/v1/apps/demoApp/services/fingerprint-api/versions/1?updateMask=servingStatus', {
        method: 'PATCH',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${accessToken}`
        },
        body: JSON.stringify({servingStatus: req.query.servingStatus}),
    });

    res.sendStatus(externalRes.ok ? 200 : 500);
});

额外检查项

  • 确认你的Cloud Function服务账号已被授予App Engine Admin角色(或包含appengine.services.update权限的自定义角色)
  • 确保API请求中的demoApp是你的实际GCP项目ID(App Engine应用ID和项目ID一致)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 01:00:30