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

Firebase Cloud Function配置管理员权限声明后仍返回403 Forbidden错误的问题排查求助

Firebase Cloud Function配置管理员权限声明后仍返回403 Forbidden错误的问题排查求助

各位大佬好,我最近在开发一个基于Firebase和React的图书馆管理应用,遇到了一个权限相关的问题,折腾了好一阵都没解决,想请大家帮忙看看:

我的需求是只有拥有admin自定义权限声明的用户,才能通过Cloud Function(createStudentUser)添加学生用户。我已经给自己的账号(UID: xDvtVII7cAV0V5g0yzpIWf70AqB3)设置了admin: true的权限声明,登出再重新登录后,客户端已经能验证到token里确实有{ admin: true }的字段,但调用这个Cloud Function时,还是会收到403 Forbidden错误,提示"FirebaseError: Must be an admin to create users"。

函数日志显示部署在us-central1,用的是Node.js 20版本的第二代函数,日志里有"auth": "VALID"的记录,但函数里打印的context.auth?.token好像并没有包含admin字段。

相关代码

Cloud Function代码(functions/index.js)

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.createStudentUser = functions.region("us-central1").https.onCall(async (data, context) => {
  console.log("Context auth token:", context.auth?.token);
  if (!context.auth || !context.auth.token.admin) {
    throw new functions.https.HttpsError("permission-denied", "Must be an admin to create users");
  }

  const { email, password, name, dob, className, studentId } = data;
  if (!email || !password || !name || !dob || !className || !studentId) {
    throw new functions.https.HttpsError("invalid-argument", "Missing required fields");
  }

  const userRecord = await admin.auth().createUser({
    email,
    password,
    displayName: name
  });

  await admin.firestore().collection("users").doc(userRecord.uid).set({
    name,
    dob,
    class: className,
    studentId,
    role: "student",
    email,
    createdAt: admin.firestore.FieldValue.serverTimestamp(),
  });

  return { studentId };
});

React端调用代码(addUser.js)

import { useState, useEffect } from "react";
import { getFunctions, httpsCallable } from "firebase/functions";
import { useAuth } from "../contexts/AuthContext";

const generateStudentId = () => Math.floor(100000 + Math.random() * 900000).toString();

function AddUser() {
  const { user, role } = useAuth();
  const [formData, setFormData] = useState({
    name: "",
    dob: "",
    className: "",
    password: ""
  });
  const [error, setError] = useState("");

  useEffect(() => {
    const checkAuth = async () => {
      if (!user || role !== "admin") return setError("Must be an admin.");
      const idTokenResult = await user.getIdTokenResult(true);
      console.log("Token claims:", idTokenResult.claims);
    };
    checkAuth();
  }, [user, role]);

  const handleAddUser = async (e) => {
    e.preventDefault();
    try {
      const newStudentId = generateStudentId();
      const email = `${newStudentId}@libraryapp.com`;
      const functions = getFunctions(undefined, "us-central1");
      const createStudentUser = httpsCallable(functions, "createStudentUser");
      await createStudentUser({ email, ...formData, studentId: newStudentId });
    } catch (err) {
      setError(err.message);
    }
  };

  return <form onSubmit={handleAddUser}>{/* Form inputs */}</form>;
}

export default AddUser;

我已经采取的步骤

  • 执行以下代码设置管理员权限声明:
const admin = require("firebase-admin");
admin.initializeApp({
  credential: admin.credential.cert(require("./service-account.json"))
});
admin.auth().setCustomUserClaims("xDvtVII7cAV0V5g0yzpIWf70AqB3", { admin: true });
  • 登出当前账号并重新登录,确保token刷新
  • 客户端验证:通过getIdTokenResult(true)获取到的token里确实包含admin: true的字段
  • 重新部署Cloud Function:执行firebase deploy --only functions

我的疑问

  • 为什么服务端的context.auth.token.admin会判断失败?明明客户端已经拿到了带admin声明的token
  • IAM权限或者Firebase服务账号的配置问题会不会导致这个403错误?
  • 有没有更有效的方法可以调试服务端收到的token权限声明,确认具体缺失了什么?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:49:32