【问题标题】:Firebase Database Rules - rules based on custom claimsFirebase 数据库规则 - 基于自定义声明的规则
【发布时间】:2020-05-28 03:54:50
【问题描述】:

我有一个 firebase 实时数据库。目前它包含两个节点admincommon

{
  "admin" : {
    "adminval" : 9898574632,
    "adminval1" : 645354536,
    "adminval2" : 7776756433
  },
  "common" : {
    "commonval" : 123433221
  }
}

我向每个用户添加了自定义声明 roles,它描述了用户在我的系统中的角色。看起来是这样的

{'roles': ['ROLE_ADMIN', 'ROLE_USER']}

现在我想限制访问,因此只有拥有声明 ROLE_ADMIN 的用户才能读/写 admin 节点,并且具有任一角色的用户都可以读/写节点 common

怎么做?我试过类似的东西:

{
    "rules": {
       "admin": {
           ".read": "auth.token.roles.contains('ROLE_ADMIN')",
           ".write": "auth.token.roles.contains('ROLE_ADMIN')"
       }
       "common": {
           ".read": "auth.token.roles.contains('ROLE_USER') || auth.token.rules.contains('ROLE_ADMIN')",
           ".write": "auth.token.roles.contains('ROLE_USER') || auth.token.rules.contains('ROLE_ADMIN')"
       }
    }
  }

【问题讨论】:

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


    【解决方案1】:

    恐怕我们不能在实时数据库安全规则中使用ArrayList。规则语言只能用于有限的类型集。你可以在这里查看文档https://firebase.google.com/docs/reference/security/database

    我们可以绕过这个限制,例如在声明中使用String

    {'roles': 'ROLE_ADMIN,ROLE_USER'}
    

    现在我们可以使用

    来检查合适的角色了
    ".read": "auth.token.roles.contains('ROLE_USER') || auth.token.rules.contains('ROLE_ADMIN')"
    

    ,因为String 支持contains 方法。正如您在评论中建议的那样,另一种选择是将声明设置为

    {'role_admin': true, 'role_user': true}
    

    然后检查规则中的角色

    ".read": "auth.token.role_admin == true || auth.token.role_user == true"
    

    旁注:我们可以在 Firestore 安全规则中使用 Listin 运算符,请参阅此处的文档 https://firebase.google.com/docs/reference/rules/rules.List

    【讨论】:

      【解决方案2】:

      我从未在自定义声明中使用过数组,所以不确定它是如何工作的,或者为什么它不适合你。

      但我确实注意到您在规则中将基于角色的访问控制和基于级别的访问控制进行了奇怪的混合,因此想提供一些一般性提示/观察:

      • 您正在使用以下两个角色标记您的管理员:ROLE_ADMINROLE_USER
      • 但是您在 common 节点中有一个 OR,用于检查任一角色。这意味着也无需向管理员提供 ROLE_USER
      • 请记住,自定义声明限制为 1000 个字节,并随每个请求一起发送。我强烈建议删除 ROLE_ 前缀,因为这已经包含在声明的 roles 名称中。
      • 如果您有一个通用逻辑,管理员可以看到比普通用户更多的信息,请考虑改用数字 access_level 声明。假设普通用户是level: 1,而管理员是level: 2。然后,您可以在您的索赔中检查最低级别:".read": "auth.token.access_level >= 1"

      【讨论】:

      • 感谢您的观点,我会考虑它们-无论如何,我的问题中的示例只是一些抽象案例-真正的问题是:我可以在自定义声明中使用数组吗?为什么contains 方法不起作用?我想拥有基于角色的访问权限,并且一个用户可以拥有多个角色,并且我想避免像 {panelAdmin: true, otherPanelAdmin: false... 这样的每个角色都拥有声明 - 这种情况的最佳方法是什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 2018-03-19
      • 1970-01-01
      • 2020-10-11
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多