问题
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