In my app I want to have a "can read"- and a "can write" view. When the app starts without existing parameters ("first time user"), then 2 random hashes are created, together with the firebase app secret they are POSTed to the PHP FirebaseTokenGenerator to receive my token.

Then I want to do this:

  • The first hash ("read hash") represents an "anonymous user" entry
  • The second hash ("write hash") represents a "key" which is a child entry of the user entry

Which looks like this:

<appname>
    users
        <read_hash>
            key
                <write_hash>
            [other user related data]
                ...

The hashes can be used as URL parameters, e.g. "myapp.com/#read_hash/write_hash"

What I want to achieve is:

  • when the user only has his read_hash (calling just "myapp.com/#read_hash"), he should be able to SEE all his entries he entered the first time (having the app create the write_hash / "key" for him). But he is not allowed to modify them.
  • When he provides his write_hash (calling "myapp.com/#read_hash/write_hash") writing to Firebase is allowed.

My security rules:

{
    "rules": {
        "users": {
            "$user": {
                ".read": "$user == auth.read_hash",
                ".write": "$user == auth.read_hash && root.child('users').child($user).child('key').val() == auth.write_hash"
            }
        }
    }
}

My problem is: How do I store the write_hash the first time without my security rule ".write" preventing writing ??

Any other idea how to achieve this? Any architectural / inconsistencies?

I'm using these libs:

  • Backbone JS with backbone-firebase.js
  • FirebaseTokenGenerator PHP

Thanks in advance.

有帮助吗?

解决方案

First, I should note that you should never put the Firebase Secret in your app. It should always be stored safely on a secure server. Your original question suggested you were sending the token down to a server from the client.

I would suggest having the read_hash be the same as a user id, and then storing a "key" at //key when the user is first created.

Then I'd suggest a rules structure as follows:

{
  "rules": {
    "$userid": {
      ".read": "$userid == auth.read_hash",
      ".write": "!data.exists() || ($userid == auth.read_hash && data.child("key") == auth.write_hash)",
    }
  }
}

其他提示

Assuming you already have the write hash's key (because you've authenticated already according to your example), this will work:

{
    "rules": {
        "users": {
            "$user": {
                ".read": "$user == auth.read_hash",
                "$key": {
                    ".write": "$user == auth.read_hash && $key === auth.write_hash"
                }
            }
        }
    }
}

If you need to create the hash before obtaining the key, for some strange use case (unlikely, but this will give you some key insights to security rules), you can do something like this:

".write": "$user == auth.read_hash && (!data.exists() || $key === auth.write_hash)"
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top