Firebase 验证firestore安全规则中的所有属性是否与用户声明匹配

Firebase 验证firestore安全规则中的所有属性是否与用户声明匹配,firebase,google-cloud-firestore,firebase-security,Firebase,Google Cloud Firestore,Firebase Security,在检索之前,我需要确保自定义声明的属性对于文档中的所有字段都为true。乍一看,函数似乎是可行的,但正如文档中所述,安全规则函数可能不包含循环,只包含一条返回语句。如何确保自定义声明在文档中具有所有值 示例文件: { e_users: true, e_user_roles: true, e_user_groups: false, e_user_accounts: true }; 安全

在检索之前,我需要确保自定义声明的属性对于文档中的所有字段都为true。乍一看,函数似乎是可行的,但正如文档中所述,安全规则函数可能不包含循环,只包含一条返回语句。如何确保自定义声明在文档中具有所有值

示例文件:

{
            e_users: true,
            e_user_roles: true,
            e_user_groups: false,
            e_user_accounts: true
        };
安全规则:

    service cloud.firestore {
      match /databases/{database}/documents {
        
        function checkClaims() {
          return resource.data.List.filter((key) => { return auth.token[key] < resource.data[key] }).length > 0 ? false : true;
        }
    
        match /permissions/{permission} {
          allow read, write: if checkClaims();
        }
      }
    }
service cloud.firestore{
匹配/databases/{database}/documents{
函数checkClaims(){
return resource.data.List.filter((key)=>{return auth.token[key]0?false:true;
}
匹配/权限/{permission}{
允许读、写:如果checkClaims();
}
}
}

您无法在安全规则中迭代列表,因此很难区分哪些值是false还是true。如果列表总是固定的,您当然可以将它们与差异进行比较:

function checkClaims(dataRoles, authRoles) {
  return dataRoles.diff(authRoles).size() == 0
}

match /path/to/{docid} {
   allow read: if checkClaims(resource.data.roles, request.auth.token.roles);
}
当你迭代你的应用程序时,这当然是有问题的。更改角色将中断所有现有的身份验证令牌,因为密钥列表不再匹配。如果您同时推送更新,那么可能只需要客户端重新验证即可获得新的声明。但这仍然不是一个有弹性的答案

一种简单的方法是丢弃错误的角色,并使用数组跟踪所需角色的列表。这允许您执行以下简单比较:

function checkClaims(dataRoles, authRoles) {
  return authRoles.hasAll(dataRoles);
}

match /path/to/{docid} {
   allow read: if checkClaims(resource.data.roles, request.auth.token.roles);
}

但这仍然不能很好地扩展,因为我们限制为1000个字符。此外,如果我们决定以后改变主意,添加访问级别而不仅仅是标志,该怎么办?一种更优雅的方法可能是将分配给用户id的角色也存储在数据库中,从而使更改更易于在将来应用。

请共享firestore文档的屏幕截图,并告诉我们您需要哪些值?