Google cloud firestore Firebase安全规则限制除一条以外的所有路径的访问?

Google cloud firestore Firebase安全规则限制除一条以外的所有路径的访问?,google-cloud-firestore,google-cloud-functions,firebase-security,Google Cloud Firestore,Google Cloud Functions,Firebase Security,问题: 对于下面不同的顶级firestore集合,如何限制对除一条路径之外的所有路径的访问 我们正在Firestore中构建一个数据模式,以支持多所学校教师的聊天应用程序 顶级firestore集合包括: /siteAdminUsers /schools /schools/{schoolId}/teachers /schools/{schoolId}/chats 下面是我们正在尝试的安全规则设置-我们在其中检查: 有效用户身份验证 userClaim变量request.auth.token.

问题:

对于下面不同的顶级firestore集合,如何限制对除一条路径之外的所有路径的访问

我们正在Firestore中构建一个数据模式,以支持多所学校教师的聊天应用程序

顶级firestore集合包括:

  • /siteAdminUsers
  • /schools
  • /schools/{schoolId}/teachers
  • /schools/{schoolId}/chats
下面是我们正在尝试的安全规则设置-我们在其中检查:

  • 有效用户身份验证
  • userClaim变量
    request.auth.token.chatFlatList中存在预期值
  • 但是,
    /messages
    的读取侦听器被阻止

    错误消息:

    FirebaseError:[代码=权限被拒绝]:缺少权限或权限不足


    service cloud.firestore{
    匹配/databases/{database}/documents{
    匹配/{document=**}{
    允许读、写:如果为false;
    }
    匹配/schools/{schoolId}/chats/{discussionId}/messages{
    允许写入:如果为false;
    允许读取:if request.auth!=null
    &&request.auth.token!=null
    &&request.auth.token.chatFlatList.val()包含($discussionId);
    }
    }
    

    详细信息

    我们对所有数据读/写都使用云函数,因此几乎在所有情况下,我们都可以阻止所有客户端访问

    一个例外是聊天讨论,我们需要在移动客户端中设置一个快照侦听器,以了解何时有新消息

    子集合注释:

    在学校,有针对学校工作人员(教师、管理人员等)的讨论会

    其中每个讨论文件包含:

  • 参与者教师ID列表
  • 实际邮件的子集合,其中每个文档都是独立发布的邮件:
  • /schools/{schoolId}/chats/{discussionId}/messages

    来自云功能的用户声明代码

    查看云函数日志,我们已经验证了userClaim正在被设置

    返回firebaseAdmin
    .auth()
    .setCustomUserClaims(
    uid{
    聊天室列表:“id1 id2 id3”
    }
    );
    
    更新#1

    尝试了以下变体,其中规则跳过/忽略对userClaim和auth.token的检查

    但是,仍然存在相同的权限错误

    service cloud.firestore{
    匹配/databases/{database}/documents{
    匹配/{document=**}{
    允许读、写:如果为false;
    }
    匹配/schools/{schoolId}/chats/{discussionId}/messages{
    允许写入:如果为false;
    允许读取:if request.auth!=null;
    }
    }
    }
    
    我认为这里的问题是您正在编写一个名为messages的集合规则

    所有匹配语句都应指向文档,而不是集合。

    您应该尝试在邮件路径后添加/{document=**},例如:

        match /schools/{schoolId}/chats/{discussionId}/messages/{document=**} {
          allow write: if false;
          allow read: if request.auth != null;
        }
    
    下面是一个解决方案(似乎正在运行),其中包括检查子字符串的
    chatFlatList
    用户声明变量(来自原始问题):

    match/schools/{schoolId}/chats/{discussionId}/messages{
    允许写入:如果为false;
    允许读取:if request.auth!=null
    &&request.auth.token.chatFlatList.matches(discussionId);
    }
    
    多亏了:

    • 这里的帖子显示,没有任何
      $
      符号来访问路径变量。我记得在一个安全规则示例代码示例中看到过这一点-可能是特定于数据库层
    • 在这里尝试一些示例输入,以了解如何创建正则表达式

  • 如果我想读写所有的藏品,而不是一本名为“backStage”的藏品,这对我来说很有用


    您是否尝试过简单地允许所有人访问消息,只是为了看看问题是否与chatFlatList的解释有关?@Doug,post更新为您描述的尝试规则设置的列表。我想知道-可能是主“全局规则”
    match/{document=**}
    ,以某种方式覆盖了邮件的自定义规则?我试图在文档中找到一些解释,说明是否至少有一条规则与true匹配,这就足够了。我不确定是否遗漏了该细节,但没有看到。谢谢你可以这样拒绝整个数据库,然后允许特定部分。这完全可行。你就是做不到允许数据库的某些部分,然后稍后拒绝。一旦允许,该用户将始终被允许。由于firebase控制台要求提供反馈-在这一点上,我想借此机会说:总体而言,不同的firebase层都是直接升级和使用的。但是-尊敬的(这里是大firebase拥护者!)-安全规则区域一直是导航/管理最麻烦(不那么直观)的区域。例如,似乎没有真正的方法来调试规则逻辑中的错误。模拟器不支持调试日志来确定哪个规则与真或假匹配,也不允许userClaim cfg。规则cfg工作或不工作:(.任何指导,非常正确:)谢谢。我明白,这些是Firebase的人正在思考的问题。
        match /schools/{schoolId}/chats/{discussionId}/messages/{document=**} {
          allow write: if false;
          allow read: if request.auth != null;
        }
    
    rules_version = '2';
        service cloud.firestore {
          match /databases/{database}/documents {
            match /{collection}/{document} {
              allow read: if true
              allow write: if (collection != "backStage");
            }
          }
        }