【问题标题】:Firebase simple blog (confused with security rules)Firebase 简单博客(与安全规则混淆)
【发布时间】:2016-04-01 11:31:42
【问题描述】:

我正在尝试基于 React + ReactFire 创建一个简单的待办事项或博客系统。

在阅读了一个小时的 firebase 教程后,对配置 firebase 安全规则感到困惑。

保存元素的代码:

this.props.itemsStore.push({
    text : this.state.text,
    done : false,
    user : this.props.user.uid
})

一切正常,但我如何才能获得所有记录仅拥​​有但授权用户?

这条规则不起作用:

  "rules": {
    "items" : {
         ".write" : "auth !== null",
         "$item" : {
            ".read": "data.child('user').val() == auth.uid"
         }
    }
  }

似乎没有办法只为一个用户获取所有记录,使用安全规则,而不是这个,我应该使用过滤器之类的东西。但同样,我不知道如何在 ReactFire 中过滤元素,并且在手册中没有任何信息。

例如它在 Parse 中是如何工作的 http://i.stack.imgur.com/l9iXM.png

【问题讨论】:

  • 问题不清楚;您是在问如何读取用户“拥有”的所有记录吗?如果是这样,则 Firebase 中没有数据的所有权。如果您要问如何允许某个经过身份验证的用户读取数据,那是一个不同的问题。问题中的规则适用于“项​​目”节点,但您的数据没有“项目”节点。你能把代码、规则和问题澄清一下吗?
  • 感谢您的回答。我认为这两种变体:读取用户“拥有”的所有记录或允许某个经过身份验证的用户读取数据,彼此非常接近。结果,我想要一个主题列表,用于我网站的主页。其中主题仅适用于创建它们的用户。
  • 这里的所有代码库github.com/Rukomoynikov/firebaseReact 获取 src/app.jsx 中主题列表的主要方法。你能帮我理解,我怎样才能获得授权用户拥有的所有主题?非常感谢) componentWillMount : function(){ this.fb = new Firebase(rootUrl + 'items/'); this.getAuthData(); this.bindAsObject(this.fb, 'items'); this.fb.on('value', this.handleDataLoaded); },

标签: authentication reactjs firebase


【解决方案1】:

Firebase 安全模型有两个常见的缺陷:

  1. permissions cascade: 授予特定级别的读取或写入权限后,您无法在较低级别取消此权限

  2. rules are not filters:(这本质上是先前陷阱的结果)您不能使用安全规则为特定用户返回不同的子集。用户可以访问某个节点,或者他们没有访问该节点的权限。

您似乎正陷入第二个陷阱。虽然用户可以访问他们作为user 的每条特定消息,但他们无法查询更高级别的items 节点,因为他们没有对它的读取权限。

如果您想保护特定用户的消息/待办事项列表,则需要为该特定用户存储该数据。

items_per_user
    $uid
        $itemid: true

这在 NoSQL 数据库中很常见,通常称为非规范化。请参阅 Firebase 网站上的 this article called "denormalization is normal"。就 Firebase API 而言,它有点过时了,但关于非规范化的架构原则仍然适用。

要为用户显示项目,您可以:

ref.child('items_per_user')
   .child(ref.getAuth().uid)
   .on('child_added', function(snapshot) {
       ref.child('items')
          .child(itemId.key())
          .once('value', function(itemSnapshot) {
               console.log(itemSnapshot.val());
          });
   })

许多刚接触 Firebase 的开发人员认为内部循环太慢而无法加载他们的数据。但是 Firebase 在处理多个请求时非常有效,因为它只为每个客户端打开一次连接,并将所有请求传递到内部循环中。

【讨论】:

  • 非常感谢。我会试试的。
【解决方案2】:

请记住,规则不是过滤器。它们允许根据标准访问节点。

这是一个简单的结构示例,其中用户 0 和 1 在其节点中存储了文本数据。

数据结构

ToDo
  a_user_id_0
    text: "some text"
    done: yes
  a_user_id_1
    text: "another text"
    done: no

规则

在此示例规则中,用户只能从 ToDo 节点中属于他们的节点读取/写入,因此路径 $user_id 将等于他们的 auth.id。它假定用户也已通过身份验证。

"ToDo": {
   "$user_id": {
      ".read": "auth != null && $user_id == auth.uid",
      ".write": "auth != null && $user_id == auth.uid"
   }
 }

如果 user_0 已通过身份验证并尝试从 a_user_id_1 节点读取/写入数据,则会失败。

【讨论】:

  • 换句话说,我必须在 users 表中保留 todos\blogpost ?
  • 在我的示例中,user_id 是父节点,经过身份验证的用户只能访问该节点内的数据。您可以选择将数据存储在具有 Record_0、Record_1、Record_2 子节点的 ToDo 父节点中。然后在每个 Record 子节点中存储 /text /user_id 等的子节点。您将修改规则以强制执行 Record 0/user_id = auth.id。不过,根据您的问题,我认为您可能正在尝试利用规则作为一种过滤器,您不应该这样做。您通过查询或事件过滤 Firebase 数据,所以我会先看看。
  • 哦 - 例如,如果您想读入并显示特定用户的 ToDo,您可以将他们的 user_id 与 toDo 一起存储,然后查询该 user_id 的所有 ToDo(无规则需要这样做)。 StackExchange 上有大量关于此操作的帖子,Firebase 入门指南中也有一些示例。
猜你喜欢
  • 2018-04-30
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
  • 2021-12-14
相关资源
最近更新 更多