How to to set firebase database rules to secure data per user?

こ雲淡風輕ζ 提交于 2020-06-17 01:49:51

问题


I'm new to Firebase, and I'm trying to understand rules where authenticated user id is to be used for securing data. I'm using Angularfire2 on the client. And I'm using email/password authentication, which works fine.

If I set my database rules to allow read and write for authenticated users, everything works fine, and I end up with the following data in the Firebase database...

{
  "notes" : {
    "-KmgjG9hxoXOTtuLTItz" : {
      "content" : "test",
      "title" : "Test note 1",
      "uid" : "iLH4Kg20shViwJebCmU8Ynp0OG23"
    },
    {
    "-Kmh5igvItrJstbAhRpq" : {
      "content" : "test",
      "title" : "Test note2",
      "uid" : "iLH4Kg20shViwJebCmU8Ynp0OG23"
    }
  }
}

Now I want to restrict read and write permissions where the authenticated user matches the user id (uid) set on each object, so I changed the rules as follow...

{
  "rules": {
    "notes": {
      ".read": "data.child('uid').val() == auth.uid",
      ".write": "newData.child('uid').val() == auth.uid"
    }
  }
}

However, this does not work. Reads fail with...

ERROR Error: permission_denied at /notes: Client doesn't have permission to access the desired data.

...and writes fail with...

FIREBASE WARNING: set at /notes/-KmgjG9hxoXOTtuLTIpG failed: permission_denied

I know that the user is authenticated because if I hard-code the user id in the rules like below, it works just fine...

{
  "rules": {
    "notes": {
      ".read": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'",
      ".write": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'"
    }
  }
}

回答1:


I was able to solve this by restructuring my data schema, putting the user id in the path, not in the object, e.g., /users/<-uid->/notes/, and using the following rules...

{
  "rules": {
    "users": {
      "$userId": {
            ".read": "$userId === auth.uid",
            ".write": "$userId === auth.uid"   
      }
    }
  }
}

As per the comments regarding "rules are not filters", I get that now. The thing that was tripping me up was where the Firebase database rules doc was referring to "children" with key-value pairs, e.g.,...

This example only allows reading if the isReadable child is set to true at the location being read.

".read": "data.child('isReadable').val() == true"

To me that implied that the JSON data structure is something like this...

{ ..., isReadable: true, ...}

But I guess that is referring to location paths, e.g., /users/fred/isReadble or something like that. Not quite sure. It seems odd. But regardless, I got it working.




回答2:


I think you are forgetting the key:

{
  "rules": {
    "notes": {
      "$key": {
        ".read": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'",
        ".write": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'"
      }
    }
  }
}

I might be missing something else but you are targeting a list with autogenerated keys (accessible in your rules with a "$somevar").



来源:https://stackoverflow.com/questions/44575194/how-to-to-set-firebase-database-rules-to-secure-data-per-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!