如果节点密钥与用户标识不同,则拒绝创建子节点。 Firebase规则

时间:2017-12-22 02:03:22

标签: firebase firebase-realtime-database firebase-security

假设我有一个数据库结构如下:

/
    favorites
        ownerid_1
            favorite1_id
                title
                link
            favorite2_id
                title
                link
        ownerid_2
            etc

我可以轻松地将Firebase权限放在这些权限中,如下所示:

{
    "rules": {
        "favorites": {
            "$owner_id": {
                ".read": "root.child('favorites').child($owner_id) == auth.uid",
                ".write": "root.child('favorites').child($owner_id) == auth.uid",
            }
        }
    }
}

然而,收藏夹是可选的,用户可以决定何时创建他们的第一个收藏夹。用户的“$ user_id”数据结构在存在之前不存在。

我正在努力弄清楚如何在/ favorites中加入验证规则,只有当密钥与用户ID相同时才允许用户创建新的子节点。

即。 ownerid_1无法创建ownerid_2节点。

我尝试过以下操作,但模拟器在未指定特定行的情况下失败:

{
    "rules": {
        "favorites": {
            ".validate": "newData.hasChild(auth.uid)",

            "$owner_id": {
                ".read": "root.child('favorites').child($owner_id) == auth.uid",
                ".write": "root.child('favorites').child($owner_id) == auth.uid",
            }
        }
    }
}

更新#1 这是没有在规则中指定任何行的日志:

Type    write
Location    /favorites/
Data    { "JhDa8owfAkTRR5qMbuvAgEyUHYL2": { "favid1": { "title": "google", "link": "www.google.com" } } }
Auth    { "provider": "google", "uid": "JhDa8owfAkTRR5qMbuvAgEyUHYL2" }
Admin   false

更新#2

我尝试了以下内容:

{
    "rules": {
        "favorites": {
            ".write": "newData.hasChild(auth.uid)",
            // This too: ".write": "newData.hasChildren([auth.uid])",
            "$owner_id": {
                ".read": "root.child('favorites').child($owner_id) == auth.uid",
                ".write": "root.child('favorites').child($owner_id) == auth.uid",
            }
        }
    }
}

哪个有效,除了它还允许成功编写以下内容:

"favorites": {
    "bad_data": "oops",
    "$owner_id": {
        "favoriteid_1": {
            "title": "google.com",
            "link": "www.google.com"
        }
    }
}

感觉我们需要像“onlyChildren”这样的选项,以便可以防止写入任意数据的用例。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

问题可能在于您尝试在执行以下操作时获取不存在的节点的子节点:

  

" root.child('收藏夹')。child($ owner_id)== auth.uid"

将规则更改为:

{
   "rules": {
       "favorites": {
           ".validate": "newData.hasChild(auth.uid)",
           "$owner_id": {
                ".read": "$owner_id === auth.uid",
                ".write": "$owner_id === auth.uid"
           }
       }
   }
}

答案 1 :(得分:0)

我改变了方法,似乎完成了这项工作。这基本上说,你可以在这里写,只要你经过身份验证并且你没有写空...但如果你这样做,那么在$ owner_id树中......

  1. $ owner_id必须与您的auth.uid匹配,确保您只能写入您的位置。
  2. 需要'title'和'link'子项,确保您不在/ favorites中写入任意数据。
  3. 数据类型必须正确,确保良好的内务管理。
  4. 以下是验证规则:

    {
        "rules": {
            "favorites": {
                ".write": "auth.uid != null && newData.val() != null",
                "$owner_id": {
                    ".read": "$owner_id == auth.uid",
                    ".validate": "$owner_id == auth.uid && 
                                  newData.hasChildren(['title', 'link']) &&
                                  newData.child('title').isString() && 
                                  newData.child('link').isString()"
                }
            }
        }
    }
    

    <强>更新 添加了空值检查。