Firebase/Firestore:如何将Auth用户添加至organization集合?
你现有的 organizations + users 双集合数据结构本身没有问题,所有安全隐患都来源于权限规则的不合理设计:你错误地将本应在后端执行的敏感操作权限开放给了前端客户端。
正确实现方案
1. 收紧Firestore安全规则,关闭客户端敏感操作权限
首先调整安全规则,从根源上禁止用户私自创建组织、篡改组织关联字段:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 禁止客户端直接创建组织 match /organizations/{orgId} { allow create: if false; // 可补充组织内读写规则:仅组织成员可操作对应组织数据 allow read, update, delete: if request.auth != null && resource.data.members.hasAny([request.auth.uid]); } // 限制用户仅能修改自身文档的非敏感字段 match /users/{userId} { allow read: if request.auth != null && request.auth.uid == userId; // 仅允许修改姓名、邮箱、头像等指定字段,禁止修改组织关联、权限等敏感字段 allow update: if request.auth != null && request.auth.uid == userId && request.resource.data.keys().hasOnly(["name", "email", "avatar"]); // 禁止客户端直接创建用户文档 allow create: if false; } } }
注意:组织关联字段、用户权限字段属于核心敏感数据,绝对不允许客户端直接修改
2. 用Auth触发器云函数处理注册后初始化逻辑
编写Firebase云函数的用户创建触发器,在用户注册成功后自动在后端执行初始化操作:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.processNewUser = functions.auth.user().onCreate(async (user) => { // 1. 创建新组织文档 const orgRef = await admin.firestore().collection("organizations").add({ name: `${user.displayName || user.email}的组织`, creatorUid: user.uid, members: [user.uid], createdAt: admin.firestore.FieldValue.serverTimestamp() }); // 2. 创建对应用户文档,关联刚创建的组织 await admin.firestore().collection("users").doc(user.uid).set({ uid: user.uid, name: user.displayName || "", email: user.email, orgId: orgRef.id, role: "admin", createdAt: admin.firestore.FieldValue.serverTimestamp() }); });
云函数运行在受信任的后端环境,默认拥有Firestore全量读写权限,不需要给客户端开放任何敏感操作权限,从根源上避免用户自行创建多个组织、篡改组织关联的问题。
3. 多组织场景适配(可选)
如果后续业务需要支持单个用户加入多个组织,可将用户文档中的orgId字段替换为orgIds数组存储所有关联的组织ID,也可单独新增organization_members集合存储用户-组织关联关系,所有关联关系的修改依然仅允许通过后端云函数执行。
内容的提问来源于stack exchange,提问作者Cyril N.
相关产品推荐
相关产品推荐

