javascript - 如何限制 Firestore 安全规则中请求的文档数量?
问题描述
我们正在为健身房和健身中心开发 SaaS 解决方案。
有3个包。第一个对他们在系统中添加的前 50 个成员免费。然后需要升级以添加更多成员。
有一个安全规则可以防止在达到该限制后添加更多成员。问题是,如果订阅升级然后降级。
假设他们升级了,总共增加了 100 名成员,然后降级为仅包括 50 名成员的免费计划。
在这种情况下,我们希望允许他们仅获取他们添加到成员集合中的最后 50 个成员。换句话说,我们希望限制对超过 50 个成员文档的请求的访问。
match /_users/{memberId} {
allow read: if isMemberAuthenticated(memberId) || isGymAuthenticated();
allow update: if isGymAuthenticated() || isMemberAuthenticated(memberId);
allow create: if isGymPaid() && isGymAuthenticated();
}
我们考虑的解决方案是:
- 在成员文档中有一个 ID 号,并限制对 ID < 订阅的任何请求的访问。问题是用户可以访问成员文档,因此可以更改他们的 ID。
- 拥有 Firebase Cloud 功能以请求成员文档并删除用户写入权限。这看起来像是 Firestore 的反模式。因为我们必须为用户对成员文档所做的任何更改实现云功能。
解决方案
如果您不希望用户更新文档中的某些字段,您可以编写一个安全规则来检查用户是否没有更改该字段的值。问题是您当前无法阻止客户端尝试请求不使用 ID 字段作为过滤器的不同查询。您也不能使用安全规则从通常属于结果的查询中过滤(删除)文档。
您可能希望研究使用request.query来帮助限制查询中的文档总数,但这需要客户端限制他们自己的结果。
使用 Cloud Functions 来控制对数据库的访问并不是一种反模式。有时需要能够强制执行安全规则无法表达的事情。有时人们也会在添加无效数据后使用 Cloud Functions 触发器来删除或清理无效数据。
推荐阅读
- java - Ubuntu apt-get install for OracleJava 8 Installer - HTTP 501 错误
- sql - 更新表并插入缺失的记录
- python - Python 中的 re.sub 与 re.findall
- python-3.x - 如何使用python selenium检查元素中是否存在文本?
- ruby-on-rails - [RAILS]:使用 ransack 按地址列出结果
- sql-server - 从 SQL Server 2017 中的 restore filelistonly 过程中丢弃列
- angular - Tomcat 上涉及 Tuckey 和 Keycloak 的角度路由
- ios - 当我使用“if let”语句解开可选的 collectionViewCell 时,为什么我的应用程序会崩溃?
- jquery - How to wait for an ajax call to finish before moving on to the next?
- mysql - MYSQL 对另一个表的子查询计数的性能