如何设置firebase数据库规则来保护每个用户的数据?

问题描述:

我是Firebase的新手,我正试图理解使用经过身份验证的用户标识来保护数据的规则。我在客户端上使用Angularfire2。我正在使用电子邮件/密码认证,这工作正常。如何设置firebase数据库规则来保护每个用户的数据?

如果我把我的数据库规则,允许读取和写入认证用户,一切工作正常,我结束了在火力地堡数据库中的以下数据...

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

现在我想限制读取和写入其中认证用户的每个对象上设置的用户ID(UID)匹配的权限,所以我改变了规则如下......

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

但是,这是行不通的。读取失败...

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

...和写入失败...

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

我知道用户进行身份验证,因为如果我硬编码像规则的用户ID下面,它工作得很好......

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

通过您的安全规则,每个用户都可以访问他们拥有的每个便条。但是没有用户可以获得笔记列表。这是按照设计工作的,在Firebase条款中称为“规则不是装修者”。我建议阅读[在Firebase文档](https://firebase.google.com/docs/database/security/securing-data#rules_are_not_filters)以及其中一个[关于它的许多问题](https:// www.google.com/search?q=site:*.com+firebase+rule+are+not+filters),包括[this original one](https://*.com/questions/14296625/)。 –

我想你忘记了关键:

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

我可能会丢失别的东西,但是您的目标是自动生成的键列表(可以在您的规则中用“$ somevar”访问)。

+0

您说得对,该规则必须在树中较低才能允许访问单个笔记。但是从'/ notes'中读取的内容仍然会随着您的规则而失败。 Firebase安全规则不能用于过滤数据。看到我对这个问题的评论的一些链接。 –

+0

我试过了。它没有帮助。 – d60402

+0

@Frank van Puffelen是对的,数据库规则不是过滤器(你没有忘记关键,但这不是重点)。我记得遇到过这个(烦人的)问题,我用云功能解决了它的一部分(https://firebase.google.com/docs/functions/)。请参阅https://*.com/questions/38687594/firebase-rule-that-works-like-a-filter以开始(它可能会强制您更改您的模式)。 – Rienk

我能够通过重构我的数据模式解决这个问题,将用户标识放在路径中,而不是在对象中,例如,使用以下规则...

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

根据有关“规则不是过滤器”的意见,我现在明白了。这是绊倒我的事情是在火力地堡数据库规则文档指的是“孩子”键 - 值对,如...

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

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

对我来说,意味着JSON数据结构是一样的东西这...

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

但我想这是指位置路径,例如,/ users/fred/isReadble或类似的东西。不太确定。这似乎很奇怪。但无论如何,我都能工作。