问题描述
我想根据用户角色在Firebase中实现写入安全规则。
我的数据结构如下所示:
<$ p $ + myapp
+用户
+ john
+ email:[email protected]
+角色
+ administrator:true
+ mary
+ email:[email protected]
+角色
+版主:true
+ ...
+文件
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
我想要 - 例如 - 只有管理员用户可以写文件。
这些是我得到的规则:
$ b $
{
rules:{
.read:true,
$ documents: {
.write:root.child('users')。child(auth.uid).child('roles')。child('administrator')。val()=== true
但它不起作用:不是前夕n个管理员用户可以写文档...
b $ b我对Firebase安全规则的理解完全有缺陷吗?
UPDATE :
在Jenny的回答之前(不管信不信:-),我确实实现了他提供的完全相同的解决方案(当然是基于Kato的评论)。
,做了一些测试,我不能让规则结构
{
rules:{
documents{
$ document{
.read:root.child('users')。child(auth.uid).child('roles')。child('documents ').child('read').val()=== true,
.write:root.child('users')。child(auth.uid).child('roles' ).child('documents')。child('write')。val()=== true
}
}
}
}
工作...我总是收到这样的警告:
<$ p $ / p> FIREBASE WARNING:on()or once()for / documents failed:Error:permission_denied:Client d没有权限访问所需的数据。
所以我想出了这个结构,而不是:
{
rules:{
documents{
.read:root.child('users')) .child('auth.uid).child('roles')。child('documents')。child('read').val()=== true,
.write:root。 child('users')。child(auth.uid).child('roles')。child('documents')。child('write')。val()=== true
}
$ b $ p
$ b 对我来说,确实有效:如果我设置角色/客户/阅读节点为真的用户,他可以阅读所有文件,否则他不能(同样写)。
我现在怀疑的是:为什么我不能让第一条规则(如Kato所建议的)有效?
你知道吗?任何可能的安全漏洞,像我所做的规则一样?
是使用$变量必要/有用的规则,即使您不必允许/拒绝可读性/可写性每个单一的
文档基于它的关键,但你只是想允许/拒绝整个节点的
的可读性/可写性?
$ b $基于你的用户记录的名字,它们不匹配 auth.uid
,可能是一个标识,例如 twitter:2544215
。
首先调整您的用户以简单登录uid存储:
+ myapp
+使用者
+ twitter:2544215
+电子邮件:[email protected]
+角色
+管理员:true
+ twitter:2544216
+ email:[email protected]
+角色
+主持人:true
+ ...
+ documents
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
接下来, dd安全规则,以便管理员可以访问文档
。您可以在这里选择一些选项,具体取决于您的特定用例。
-
让管理员可以访问每个文档的内容:
{
rules:{
documents:{
$ documents :{
.write:root.child('users')。child(auth.uid).child('roles')。child('administrator')。val()=== true
$ c $ $ $ $ $ $或者,也可以让他们访问整个集合:
{
rules:{
documents:{
.write:root.child('users')。child(auth.uid).child('roles')。child('administrator')。val )=== true
}
}
这两个变量之间的区别在于 $ documents
变量,它将安全规则进一步移动到层次结构中。
(这大部分只是@Kato的意见汇总到答案表格中)
I would like to implement "write" security rules in Firebase depending on users roles.
My data structure is like this:
+ myapp
+ users
+ john
+ email: "[email protected]"
+ roles
+ administrator: true
+ mary
+ email: "[email protected]"
+ roles
+ moderator: true
+ ...
+ documents
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
I want - for example - that only administrator users can write documents.
These are the rules I've come to:
{
"rules": {
".read": true,
"$documents": {
".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
}
}
}
But it doesn't work: not even administrator users can write documents...
Is my understanding of Firebase security rules totally flawed?
UPDATE:Just before Jenny's answer (believe it or not :-), I did implement the exact same solution he provides (of course based on Kato's comment).
Though, making some tests, I could not let the rules structure
{
"rules": {
"documents" {
"$document" {
".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
}
}
}
}
work... I always got a warning like this:
"FIREBASE WARNING: on() or once() for /documents failed: Error: permission_denied: Client doesn't have permission to access the desired data. "
So I came up with this structure, instead:
{
"rules": {
"documents" {
".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
}
}
}
Which indeed works, for me: if I set a roles/customers/read node to true on a user he can read all documents, otherwise he can't (and the same for write).
My doubts now are:
- why I could not let the first rule (as suggested by Kato) work?
- do you see any possible security hole in a rule like the one I did came up with?
- are rules using "$" variables necessary/useful even if you don't have to allow/deny the readability/writeability of each singledocument based on it's key, but you just want to allow/deny thereadability/writeability of a node as a whole?
解决方案 Based on the names of your user records, they don't match auth.uid
, which is probably a Simple Login id, such as twitter:2544215
.
Start by adjusting your users to be stored by their Simple Login uid:
+ myapp
+ users
+ twitter:2544215
+ email: "[email protected]"
+ roles
+ administrator: true
+ twitter:2544216
+ email: "[email protected]"
+ roles
+ moderator: true
+ ...
+ documents
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
Next, add a security rule so that administrators can access documents
. You have a couple options here, depending on your specific use case.
To give administrators write access to contents of each document:
{
"rules": {
"documents": {
"$documents": {
".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
}
}
}
}
Or, alternatively, give them access to the whole collection:
{
"rules": {
"documents": {
".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
}
}
}
The difference between these two being the $documents
variable that moves the security rule one step further into the hierarchy.
(This was mostly just an aggregation of comments by @Kato into answer form)
这篇关于Firebase:根据用户角色设置安全规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!