Firebase simple blog (confused with security rules

2019-08-09 08:27发布

I'm trying to create a simple todo or blog system based on React + ReactFire.

And after a hour of reading firebase tutorial confused about configuring firebase security rules.

Code for saving element :

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

Everything ok, but how i can get all records what owns only but authorized user?

This rules doesn't works :

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

Seems to there no way to get all records only for one user, with security rules, instead of this, i should use something like filter. But again, i don't know how to filter elements in ReactFire, and in manuals no information.

As example how does it work in Parse http://i.stack.imgur.com/l9iXM.png

2条回答
我命由我不由天
2楼-- · 2019-08-09 09:14

The Firebase security model has two common pitfalls:

  1. permissions cascade: once you've granted a read or write permission on a specific level, you cannot take this permission away at a lower level

  2. rules are not filters: (this is essentially a consequence of the previous pitfall) you cannot use security rules to return a different subset of children for specific users. Either a user has access to a node, or they don't have access to it.

You seem to be falling for that second pitfall. While the user can access each specific message that they are the user for, they cannot query the higher-level items node since they don't have read access to it.

If you want to secure a list of messages/todos for a specific user, you will need to store that data for that specific user.

items_per_user
    $uid
        $itemid: true

This is quite common in NoSQL database and is often called denormalizing. See this article called "denormalization is normal" on the Firebase web site. It's a bit outdated as far as the Firebase API goes, but the architectural principles on denormalizing still apply.

To then show the items for a user, you'd do:

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());
          });
   })

Many developer new to Firebase think that the inner loop will be too slow to load their data. But Firebase is very efficient when it comes to handling multiple requests, since it only opens a connection once per client and pipelines all the requests in the inner loop.

查看更多
别忘想泡老子
3楼-- · 2019-08-09 09:16

Keep in mind, Rules are not filters. They allow access to nodes based on criteria.

Here's an example simple structure where users 0 and 1 have stored text data within their node.

Data Structure

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

Rules

In this example rule, users can only read/write from nodes that belong to them within the ToDo node, so the path $user_id would be equal to their auth.id. It assumes the users has authenticated as well.

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

If user_0 was auth'd and attempted to read/write data from a_user_id_1 node, it would fail.

查看更多
登录 后发表回答