您的安全规则应该完全符合您的代码要求,仅此而已。这被称为最小权限原则,是确保恶意用户不能比您自己的代码所做的更多操作的最佳方法。
让我们看看依次使读取和写入更安全。
保护读取
您的规则目前允许任何人读取整个数据库。但是您的代码不会读取整个数据库。相反,它只读取即将播出的节目列表。因此,您应该只允许阅读即将播出的节目:
match /databases/{database}/documents {
match /upcoming_shows/{document} {
allow read: if true;
}
所以现在用户只能从一个集合中读取:名为 upcoming_shows 的集合。
如果您实际上有一个所有节目的列表,并且您的代码只读取using a query 的即将到来的节目,您也可以secure that query 以便有人阅读所有 节目被拒绝。
正如开头所说:您的规则应该只允许您的代码需要的内容,仅此而已。
保护写入
您说过只有管理员才可以在登录时写入数据。但现在任何登录 Firebase 身份验证的人都可以在您的整个数据库中写入任何他们想要的内容。因此,恶意用户可以从您的应用程序中获取配置,使用该配置调用 Firebase 进行登录,然后删除您的所有数据,向其中添加他们自己的假节目,或者只是在数据库中创建一个完全不同的数据集,即然后你付钱。
您需要更好地保护两个部分:
- 只有管理员可以写。
- 他们只能添加节目。
只有管理员可以写
您似乎认识管理员,因此您可能可以在 Firebase 控制台中找到他们的 UID,并在您的规则中简单地硬编码:
allow write: if request.auth == "uid of your known administrator";
现在有了这些规则,由于 Firebase 确定用户的 UID 并且不能被欺骗,因此您已确保只有您识别的一个人可以写入数据库。
这种模式有很多变体,但这是一个很好的第一步。
他们只能添加节目
通过上述更改,我们已经确保只有管理员可以写,但他们仍然可以写任何他们想要的东西。最小权限原则规定我们应该确保他们也只能写他们必须能够写的东西。在您的情况下,这是“添加新节目”。
这又分为两个要求:
-
管理员只能写节目,不能写其他类型的数据,也不能写数据库其他地方的数据。
-
管理员只能添加节目,这意味着他们不能更新或删除节目。
只允许写节目
第一个要求是双重的,第一个类似于我们为读取所做的:我们希望确保它们只能写入 upcoming_shows 集合:
match /upcoming_shows/{document} {
allow write: if request.auth == "uid of your known administrator";
}
第二部分是他们只能在那里写shows,这意味着你要validate the data that they write。您将只想允许您的代码实际写入的字段(再次)规则应该只允许代码所做的事情,仅此而已。这可能包括验证演出的日期是否在未来,如果这也是您的用例所需要的。
只允许添加节目,不允许更新/删除节目
最后你的用例说他们只能添加节目,我认为不能更新和/或删除它们。我们可以使用granular rules 来实现该要求:
match /upcoming_shows/{document} {
allow create: if request.auth == "uid of your known administrator" &&
/* the validation rules from the previous step */;
}