首页 > 解决方案 > Firebase实时数据库-如果值为null,则读取路径时权限被拒绝

问题描述

我正在尝试读取我的 Firebase 实时数据库/users/uid1中的路径,其中路径的值为null。实际上,它不存在。我的安全规则允许在路径上读取(规则如下)。实际读取数据时,权限被拒绝。

安全规则如下:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "root.child('users').child($uid).child('mUser_Role').child('mRole_PermissionLevel').val() > 400 || root.child('users').child(auth.token.phone_number).child('mUser_Role').child('mRole_PermissionLevel').val() == 500"
      }
    }
  }
}

尝试阅读失败/users/uid1,权限/users/myuid/mUser_Role/mRole_PermissionLevel == 500true拒绝。

当值为 的情况下,Firebase 如何确定应拒绝权限null?不应该允许读取并返回wheredataSnapshot吗 ?dataSnapshot.exists()false

我没有data在路径上指定任何规则,null并且当路径上的值不是时读取成功null


编辑 - 重现这个场景 -

1. 将 JSON 上传到 Firebase 实时数据库的根目录-

{
  "users" : {
    "+9198100xxxxx" : {
      "mUser_Id" : "+9198100xxxxx",
      "mUser_ProfilePicUrl" : "url",
      "mUser_Role" : {
        "mRole_Name" : "Employee",
        "mRole_PermissionLevel" : 500
      }
    },
    "+9198100yyyyy" : {
      "mUser_Id" : "+9198100yyyyy",
      "mUser_ProfilePicUrl" : "url",
      "mUser_Role" : {
        "mRole_Name" : "Employee",
        "mRole_PermissionLevel" : 500
      }
    }
  }
}

2. Firebase 实时数据库规则(实际用于此节点) -

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "root.child('users').child($uid).child('mUser_Role').child('mRole_PermissionLevel').val() > 400 || root.child('users').child(auth.token.phone_number).child('mUser_Role').child('mRole_PermissionLevel').val() == 500"
      }
    }
  }
}

3.使用Firbease安全规则模拟器 -

模拟类型 -read

位置 - /users/+9198100zzzzz(模拟读取失败)

位置 - /users/+9198100yyyyy(模拟读取成功)

已认证 -yes

提供者 -custom

身份验证令牌有效负载 -

{
  "provider": "phoneauth",
  "uid": "6f2eed52-b2e9-409a-b5f1-dc307c7f6671",
  "token":{
      "phone_number": "+9198100xxxxx"
  }
}

在此处输入图像描述 在此处输入图像描述

标签: firebasefirebase-realtime-databasefirebase-security

解决方案


不存在的节点评估为null,因此您的规则基本上评估为:

null > 400 || 500 == 500

使用的规则引擎是强类型的,这意味着null > 400引发错误而不是评估为false.

解决方案是先检查节点是否存在,然后再比较其值。所以:

".read": "
 (
  root.child('users').child($uid).exists() &&
  root.child('users').child($uid).child('mUser_Role').child('mRole_PermissionLevel').val() > 400
 ) || (
  root.child('users').child(auth.token.phone_number).exists() &&
  root.child('users').child(auth.token.phone_number).child('mUser_Role').child('mRole_PermissionLevel').val() == 500
 )
"

推荐阅读