首页 > 解决方案 > Firestore 规则允许任何经过身份验证的用户写入子集合,但只有该子集合的所有者可以读取?

问题描述

我是 Firebase 的新手,我正在开发一个类似于考勤计划的 Firestore 应用程序。教师和学生都可以使用它,但只有教师才能看到学生的数据。学生必须登录才能获得 uid,当他们“参加”课程时,会创建一个以 uid 作为名称的节点,其字段包含他们的姓名、学生 ID 等。树看起来像这样,老师当然可以接触到他们所有的孩子:

teachers/{teacherID}/classes/{classID}/students/{studentID}

(我知道这不是很肤浅,但它使基于班级的学生获取更简单,查询更少。这是否也需要更改?)

当然,教师也会有姓名、教师 ID、电子邮件等信息,学生无法读取或写入/更新/删除,但会读取教室信息,如 roomNumber、timeSlot 等(当然只有教师可以更新此信息)。这看起来如何才能安全且不受滥用?我是否需要担心规则继承/级联?

match /teachers/{teacherID} {
      allow read, write: if teacherID == request.auth.uid;
    }

match /teachers/{teacherID}/classes/{classID} {
      allow write: if teacherID == request.auth.uid; //How do I get this value here?
      allow read: if request.auth.uid != null;
    }
match /teachers/{teacherID}/classes/{classID}/students/{studentID} {
      allow read: if teacherID == request.auth.uid; //and here?
      allow write: if request.auth.uid != null;
    }

同样相关:教师和学生角色不存在,因为学生也可以将此出勤应用程序用于学生俱乐部/会议,其中俱乐部将是“班级”,而该“学生”将成为“老师”。

标签: google-cloud-firestorefirebase-security

解决方案


如果您在子句中指定递归通配符( =**),则安全规则中授予的访问权限仅级联到嵌套集合。match由于您不会在任何地方这样做,因此您当前的访问规则不会级联。

在这种情况下,您可能希望在teacher的访问规则上放置一个递归通配符,因为您似乎也希望他们访问子集合的级联:

match /teachers/{teacherID=**} {
  allow read, write: if teacherID == request.auth.uid;
}

推荐阅读