javascript – 使用基于firebase查询的规则来保护数据(使用orderByChild和不可索引的键)

更新/回答2018年2月

似乎基于查询的规则目前无法为realtimeDB结构提供这种级别的安全性/优雅.像这样的东西需要嵌套排序,变量’key’索引(与当前的“indexOn”:“.value”一样,或者还有一些其他魔法尚未由firebase团队设想.

与此同时,我绝对可以推荐阅读基于查询的规则:

> https://firebase.googleblog.com/2018/01/introducing-query-based-security-rules.html
> https://firebase.google.com/docs/database/security/securing-data#query_based_rules

原始问:给出一个firebase实时数据库节点列表,每个节点都有一个命名的组列表,以及一个我想要查找的组 – 我希望通过基于查询的规则限制访问,以便只有给定组的节点是回.其他一切都应该被视为私人数据.

E.g DB:

[lookup]: {
  id1: {
    groups: {
      randomgroup1: true
    },
  },
  id2: {
    groups: {
      randomgroup1: true,
      randomgroup2: true
    },
  }
}

实时数据库规则:

"lookup": {
  ".read": "query.orderByChild != null && query.equalTo != null",
  "$uid": {
    ".indexOn": "groups"
  }
}

有效的请求/查询:

const $group = 'randomgroup2';
firebase.ref('lookup').orderByChild(`groups/$group`).equalTo(true).once('value')

以上正确返回id2:{groups:{randomgroup1:true,randomgroup2:true}}但是由于组名缺少索引,整个[lookup]节点被发送到客户端进行过滤,即数据是不安全.

如何做到最好,以保持安全?我愿意改变节点的结构或更新安全规则.

注意:这对于经过试验和测试的多对多关系设置(即,火基强暴复制数据库101)是完全可能的,使用上述技术同样可以(并且安全),其中每个记录仅需要1个组.

最佳答案 您当前的数据结构非常适合查找给定ID的组.

但是要查找给定组的ID,您需要执行查询,就像您尝试的那样.

对于要在服务器上执行的查询,您需要在您订购的字段上定义索引,因此group / $group.这意味着您需要在每个组/ randomgroup1,groups / randomgroup2等上定义索引.这是不可行的.

这就是为什么你要在数据结构中添加另一个节点,其中包含你想要查找的信息:每个随机组的id:

[lookup2]: {
  randomgroup1: {
    id1: true
  },
  randomgroup2: {
    id1: true,
    id2: true
  }

现在使用此结构,您还可以直接查找给定组的ID.

有关此类双向查找的更多信息,请参阅:

> Firebase query if child of child contains a value
> Many to Many relationship in Firebase

点赞