【问题标题】:How to filter/hide attributes in Firebase如何在 Firebase 中过滤/隐藏属性
【发布时间】:2016-09-25 23:08:30
【问题描述】:

如何在 Firebase 中过滤掉/隐藏机密属性?

例如,如果我有一个数据存储:

"people": {
  "ivan": {
    "age": 23,
    "location": "Australia"
    "password": "123",
    "underGroundLover": "JLo"
  }
}

我想对普通观众隐藏passwordunderGroundLover,同时他们能够获取节点ivan

据我了解,Firebase 的授权/安全规则/节点获取逻辑只是“全有或全无”,因此如果我想从节点中过滤掉一些秘密属性,我将不得不:

  1. 在将数据传递给用户之前,使用我自己的服务器/lambda 过滤掉机密。这违背了 BAAS 的目的。

  2. 使用一种奇怪的非规范化数据结构来分隔公共可访问属性和需要权限的属性。这将引入大量的 n+1 查询。

选项 2 的带有规则的非规范化数据结构将是这样的(我知道数据和规则不能同时存在):

{
  "rules": {
    "public": {
      "people": {
        ".read": true,
        "ivan": {
          "age": 23,
          "location": "Australia"
          "passwordRef": "/non-public/people/ivan/password",
          "underGroundLoverRef": "/non-public/people/ivan/underGroundLover"
        }
      }
    },
    "nonPublic": {
      "people": {
        ".read": false,
        "ivan": {
          ".read": false,
          "password": {
            ".read": if(user === "ivan" || user.group = "admin" || user.group === "ivan's parent")
          },
          "underGroundLover": {
            ".read": if(user !== "ivan's wife")
          }
        }
      }
    }
  }
}

还有其他更有效的方法可以实现过滤器吗?如果 Firebase 可以回答我,我还想知道为什么安全规则或数据获取必须是全有或全无?如果 Firebase 可以根据规则过滤/隐藏数据库不是很好吗?

【问题讨论】:

  • 您不能隐藏节点的某些部分。用户可以读取整个节点,也可以不读取。我们可以同意,如果您加载部分节点或使用安全规则过滤数据会很好。但归根结底,重要的是它是如何工作的:读取操作永远不会根据安全规则返回它读取的位置的子集。
  • 嗯,我明白了。看起来这是我们反对在生产中使用 Firebase 的交易破坏者......
  • 在 NoSQL 数据库中建模/复制数据以匹配您的用例是很常见的。许多开发人员使用 NoSQL 解决方案实现了令人难以置信的可扩展性的原因是他们接受了这些概念并在其中工作以满足他们的需求。为了更适应这种方法,我强烈推荐阅读NoSQL data modelling
  • 如果您担心加载连接的数据,请复制该数据和/或阅读stackoverflow.com/questions/35931526/…
  • 是的,我明白你的意思是最小化 n+1 效应。我猜在应用程序达到一定规模之前,这还不错。实际上,我可以向 Firebase 推荐一个功能吗?如果 Firebase 可以支持 SQL 中的include、MongoDb 中的populate,甚至只是一般的batch,那么我的 n+1 问题可以通过我展示的示例结构从 FIrebase 方面彻底解决。

标签: firebase data-structures firebase-realtime-database firebase-security nosql


【解决方案1】:

一个可能的解决方案是简单地保留重复数据。 NoSQL 数据库和磁盘空间的常见做法很便宜...

致所有想了解 Ivan 的用户:

"people_public": {
  "ivan": {
    "age": 23,
    "location": "Australia"
  }
}

还有只属于伊万本人的私有节点

"people_private": {
  "ivan": {
    "age": 23,
    "location": "Australia"
    "password": "123",
    "underGroundLover": "JLo"
  }
}

公共用户通常只会查看 Ivan 的数据,而不是对其进行修改,因此如果 Ivan 决定搬到克利夫兰,他将是更新数据的人,因此使用多位置更新更新两个节点。

这也确实简化了安全规则,因为用户只能在 people_private 节点中访问自己的节点。

【讨论】:

  • 杰伊的回答很好!我希望我可以单独对有关这如何简化您的安全规则的段落进行额外投票。 :-)
  • 如果我理解正确,您将把.read 规则逻辑放在people_private/ivan 节点而不是其各个子节点下,这意味着这种结构缺乏管理属性权限的灵活性每个用户组(例如 admin 组、Ivan 的父组和 Ivan 的妻子组)。
  • 是的.. 不!是的,您可以向 people_private 添加一条读取规则,只允许 ivan 修改他们自己的节点。但是,更好的方法是创建一个 /ivans_peeps 的节点,该节点具有 uid: true 允许修改 ivan 节点的用户。然后,您的规则可以验证用户是否经过身份验证,并且他们的 uid 是否出现在 /ivans_peeps 节点中。这可以是管​​理员节点或其他各种节点。 @FrankvanPuffelen 可能有其他建议。
猜你喜欢
  • 1970-01-01
  • 2015-08-23
  • 2019-12-13
  • 2021-11-02
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多