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

如何在Firebase中创建并使用M2M令牌实现云函数间认证?

云函数A调用云函数B:获取服务账户访问令牌并验证

核心实现思路

在云函数环境中,无需手动管理服务账户密钥文件,可借助Google Auth Library自动获取默认服务账户的ID Token,用于调用受保护的云函数B。同时调整B的验证逻辑,仅允许指定服务账户的请求。

步骤1:为云函数A安装依赖

在云函数A的项目目录下执行:

npm install google-auth-library node-fetch

步骤2:云函数A中获取服务账户ID Token并调用B

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { GoogleAuth } = require('google-auth-library');
const fetch = require('node-fetch');

admin.initializeApp();

// 生成针对目标云函数的ID Token
async function getServiceAccountIdToken(targetFunctionUrl) {
  const auth = new GoogleAuth();
  const client = await auth.getIdTokenClient(targetFunctionUrl);
  return client.idTokenProvider.fetchIdToken(targetFunctionUrl);
}

exports.userBeforeCreate = functions.auth.user().beforeCreate(async (user) => {
  // 替换为你的云函数B的HTTPS端点
  const functionBUrl = 'https://你的区域-你的项目ID.cloudfunctions.net/functionB';
  
  try {
    // 获取服务账户ID Token
    const idToken = await getServiceAccountIdToken(functionBUrl);
    
    // 调用云函数B
    const response = await fetch(functionBUrl, {
      method: 'POST', // 根据B的实际请求方法调整
      headers: {
        'Authorization': `Bearer ${idToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ userData: user }) // 传递需要的参数
    });
    
    if (!response.ok) {
      throw new Error(`调用云函数B失败: ${await response.text()}`);
    }
    
    const result = await response.json();
    // 处理B返回的结果
    console.log('云函数B返回结果:', result);
  } catch (error) {
    console.error('处理请求时出错:', error);
    throw error; // 抛出错误以触发函数重试(可选)
  }
});

步骤3:调整云函数B的验证逻辑,仅允许指定服务账户访问

修改B的代码,验证令牌的签发主体为你的项目默认服务账户:

const admin = require('firebase-admin');
const functions = require('firebase-functions');

admin.initializeApp();

exports.functionB = functions.https.onRequest(async (req, res) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(403).send('缺少有效授权令牌');
  }

  const idToken = authHeader.split('Bearer ')[1];
  
  try {
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    
    // 替换为你的项目默认服务账户邮箱(格式:项目ID@appspot.gserviceaccount.com)
    const allowedServiceAccount = '你的项目ID@appspot.gserviceaccount.com';
    
    // 验证令牌主体为允许的服务账户
    if (decodedToken.sub === allowedServiceAccount) {
      // 验证通过,处理业务逻辑
      res.status(200).json({ status: 'success', message: '请求已处理' });
    } else {
      res.status(403).send('无权访问此端点');
    }
  } catch (error) {
    console.error('令牌验证失败:', error);
    res.status(403).send('令牌无效或已过期');
  }
});

步骤4:配置权限,允许A的服务账户调用B

在Google Cloud Console中:

  • 找到云函数B的详情页面
  • 进入「权限」标签页
  • 添加成员:输入你的项目默认服务账户邮箱(项目ID@appspot.gserviceaccount.com)
  • 为其分配「Cloud Functions Invoker」角色
  • 保存配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:25:30