【问题标题】:Firebase security rule with user based access - Permission denied error具有基于用户访问权限的 Firebase 安全规则 - 权限被拒绝错误
【发布时间】:2020-09-11 03:45:20
【问题描述】:

我的应用尝试读取“站点”集合下的文档。我做了一个模拟读取操作,效果如下:

Profile/'actual profile id'/Sites/'actual site id'

这个模拟阅读可能是因为我正在阅读一个预定义的文档。我不确定。

我的安全规则如下:

match /Profile/{profile}/Sites/{site} {
 allow read: if isOneOfRoles (get(/databases/$(database)/documents/Profile/$(profile)/Sites/$(site)),['FULL', 'OWNER', 'VIEW']);
}

function getRole(rsc) {return rsc.data.SHARED_WITH[request.auth.token.email];}

function isOneOfRoles(rsc, array) {return isSignedIn() && (getRole(rsc) in array);}

最后我的查询如下:

Firestore.instance.collection('Profile/${_firebaseUser.uid}/Sites')
        .where('ARCHIVE',isEqualTo: false)
        .orderBy('DATE',descending: true)
        .getDocuments();

我的数据库结构如下所示: 我在控制台中收到权限被拒绝错误。需要帮助以了解我哪里出错了?

【问题讨论】:

  • 请编辑问题以显示完整规则,包括匹配语句。您现在展示的部分规则不足以理解正在发生的事情。您还应该在数据库中显示用于决定是否允许访问的相关数据。

标签: javascript firebase google-cloud-firestore firebase-security


【解决方案1】:

规则拒绝您的查询,因为 Firebase security rules are not filters。您不能使用规则来限制与查询匹配的文档集。

现在,您的查询要求知道 ARCHIVE = true 的 所有 文档,但您的规则不允许查询依赖于基于查询中数据的其他一些文档的文档.规则引擎不会读取和检查每一个其他文档 - 这根本无法扩展。

您必须找到另一种结构化数据的方法,可能是将权限放入每个文档本身,并将这些权限用作查询过滤器的一部分。

【讨论】:

  • 谢谢道格。但据我了解,权限“在每个文档中”本身,即具有角色的电子邮件,这正是我要阅读的文档。即使我删除了“where”子句,也没有什么不同。
  • 这仍然是因为安全规则不是过滤器。查询总是会被拒绝,因为规则无法提前断言是否总是允许获取所有文档。它不会为每个文档执行 get() - 不会扩展,它会超过每个规则评估的最大 10 次获取,否则将非常昂贵。
  • 你能帮我举个例子,看看你如何能以更好的方式工作
  • 问题是您正在尝试使用规则作为查询过滤器查询 Firestore,但是正如回答者所说,一旦其中一个条目失败,所有查询都会被拒绝(bc of permissions)。因此,您必须执行两步查询: 1)首先获取与用户共享的文档,然后逐一访问这些文档。这可以通过添加另一个集合 shared 与要共享的元素来完成
  • 2) 在配置文件信息中,您必须添加另一个条目shared-docs,其中包含与该特定用户共享的元素数组,以完全重构数据库
猜你喜欢
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 2020-03-22
  • 2021-10-20
  • 1970-01-01
  • 2016-09-25
相关资源
最近更新 更多