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

如何通过Firebase Admin SDK实现公、私有API端点共存?

我来帮你梳理下怎么把Express应用部署到Firebase Hosting+Cloud Functions,同时区分公网和需要身份验证的私有API端点,用Firebase Admin SDK搞定令牌验证的完整流程~

整体架构说明

简单说就是:前端静态资源托管在Firebase Hosting,后端Express服务跑在Cloud Functions上;前端请求后端时,私有接口需要携带Firebase ID令牌,通过我们写的中间件验证身份后才能访问,公网接口则直接开放。

步骤1:初始化项目与安装依赖
  • 先确保本地装了firebase-tools,没装的话跑npm install -g firebase-tools,然后登录Firebase账号:firebase login
  • 初始化项目:在项目根目录执行firebase init,按提示勾选Functions和Hosting
  • 进入functions目录,安装必需依赖:npm install express firebase-admin cors
  • 注意:Firebase Functions环境会自动给Admin SDK注入权限,不用手动下载服务账号密钥,直接初始化就行
步骤2:编写身份验证中间件

把验证ID令牌的逻辑抽成可复用的中间件,这样所有私有接口都能直接用:

const admin = require('firebase-admin');
admin.initializeApp();

// 验证Firebase ID令牌的中间件
const authenticate = async (req, res, next) => {
  const authHeader = req.headers.authorization;
  // 检查请求头是否带了Bearer令牌
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ error: '请提供有效的身份令牌' });
  }

  const idToken = authHeader.split(' ')[1];
  try {
    // 验证并解码令牌
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    // 把解码后的用户信息挂载到req对象上,后续路由可以直接用
    req.user = decodedToken;
    next(); // 验证通过,继续执行后续路由逻辑
  } catch (error) {
    return res.status(403).json({ error: '身份令牌无效或已过期' });
  }
};
步骤3:配置Express路由(区分公网/私有)

创建Express实例,分别定义无需验证的公网接口和需要验证的私有接口:

const express = require('express');
const cors = require('cors');
const functions = require('firebase-functions');
const app = express();

// 全局中间件:处理跨域和JSON请求解析
app.use(cors({ origin: true }));
app.use(express.json());

// 👉 公网API端点:所有人可直接访问
app.get('/api/public', (req, res) => {
  res.json({ message: '这是一个公网端点,无需登录就能访问~' });
});

// 👉 私有API端点:必须通过authenticate中间件验证身份
app.get('/api/private', authenticate, (req, res) => {
  res.json({ 
    message: `欢迎访问私有端点,${req.user.email}!`,
    userInfo: {
      uid: req.user.uid,
      email: req.user.email,
      emailVerified: req.user.email_verified
    }
  });
});

// 把Express应用导出为Cloud Function
exports.api = functions.https.onRequest(app);
步骤4:配置Hosting重写规则

让前端的API请求自动转发到Cloud Functions,修改项目根目录的firebase.json:

{
  "hosting": {
    "public": "public", // 前端静态资源目录
    "rewrites": [
      {
        "source": "/api/**", // 所有/api开头的请求
        "function": "api"    // 转发到名为api的Cloud Function
      }
    ]
  }
}
步骤5:前端请求示例

前端调用私有接口时,需要先从Firebase Auth获取当前用户的ID令牌,再放到请求头里:

import { getAuth, getIdToken } from "firebase/auth";

const auth = getAuth();
const currentUser = auth.currentUser;

if (currentUser) {
  getIdToken(currentUser)
    .then(idToken => {
      // 调用私有API
      fetch('/api/private', {
        headers: {
          'Authorization': `Bearer ${idToken}`
        }
      })
      .then(res => res.json())
      .then(data => console.log('私有接口返回:', data))
      .catch(err => console.error('请求失败:', err));
    })
    .catch(err => console.error('获取令牌失败:', err));
} else {
  console.log('用户未登录,无法访问私有接口');
}
部署与测试
  • 部署Cloud Functions:firebase deploy --only functions
  • 部署Hosting:firebase deploy --only hosting
  • 测试公网接口:直接访问https://你的项目ID.web.app/api/public,应该返回正常响应
  • 测试私有接口:未带令牌会返回401,带有效令牌返回用户信息,无效/过期令牌返回403

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:09:35