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

如何让RTK Query传递的认证在Firebase实时数据库安全规则中生效?

问题:Firebase实时数据库安全规则校验失败,auth对象为null

前端已通过Firebase登录API完成认证,通过认证变更监听器获取令牌并传递至后端,相关代码配置如下:

RTK Query通用配置

reducerPath: "api",
baseQuery: fetchBaseQuery({
  baseUrl: "https://us-central1.cloudfunctions.net/api",
  mode: "cors",
  prepareHeaders: (headers) => {
    headers.set("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
    headers.set("Access-Control-Allow-Origin", "*");
    headers.set("Access-Control-Allow-Headers", "Content-Type");
    const authToken = localStorage.getItem("AuthToken");
    if (authToken) headers.set("authorization", authToken);
    return headers;
  },
}),
endpoints: (builder) => ({
  getWorkouts: builder.query<GetWorkoutList, string>({
    query: (userId) => ({
      url: `/workouts/${userId}`,
    }),
  }),
// ---rest of endpoints---

前端认证状态监听代码

useEffect(() => {
  const unsubscribe = onAuthStateChanged(auth, async (userInfo) => {
    setUser(userInfo);
    if (userInfo === null) {
      localStorage.clear();
    } else {
      const token = await userInfo.getIdToken(true);
      localStorage.setItem("AuthToken", `Bearer ${token}`);
    }
  });
  return unsubscribe;
}, [user]);

云函数令牌验证代码

const decodedIdToken = await adminApp.auth().verifyIdToken(idToken);

实时数据库安全规则

"users":{
  "$userId":{
    ".write": "$userId == auth.uid",
    ".read": "$userId == auth.uid",
  },
}

当前问题:使用Admin权限访问实时数据库时会绕过安全规则,导致数据库中的auth对象为null,无法通过规则校验。需要明确缺失的关键步骤,让请求实时数据库时携带认证对象,使安全规则生效。


关键解决步骤

核心问题是:默认情况下Firebase Admin SDK访问实时数据库时会以特权身份操作,直接跳过安全规则,不会自动携带用户的认证信息。要让安全规则生效,必须在云函数中模拟用户身份访问数据库,具体操作如下:

  1. 保留令牌验证步骤
    你已经通过verifyIdToken拿到了解码后的decodedIdToken,其中包含用户的uid,这一步无需改动,继续保留即可。

  2. 创建绑定用户身份的数据库引用
    不要直接使用adminApp.database().ref()这种特权引用,而是通过withAuth()方法生成绑定用户UID的数据库引用。基于该引用的所有操作都会触发安全规则,且规则中的auth.uid会被设置为指定的用户ID。

    示例代码:

    // 验证令牌并提取用户UID
    const decodedIdToken = await adminApp.auth().verifyIdToken(idToken);
    const userId = decodedIdToken.uid;
    
    // 创建带用户身份的数据库引用
    const userDbRef = adminApp.database().ref().withAuth({ uid: userId });
    
    // 使用该引用执行数据库操作,比如读取用户数据
    const userData = await userDbRef.child(`users/${userId}`).get();
    
  3. 清理前端不必要的CORS头设置
    你在RTK Query的prepareHeaders中设置的Access-Control-Allow-Origin等CORS头属于后端响应头,不应该由前端请求设置。前端只需要确保请求开启跨域模式即可,这些头应该在云函数的响应中配置,否则可能引发请求异常。

完成以上修改后,数据库操作会严格遵守安全规则,auth对象不再为null,auth.uid会匹配当前用户的UID,从而通过规则校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:35:40