Firebase 用户访问其他用户数据的安全规则

问题描述 投票:0回答:1

我希望我的 flutter 应用程序中的用户能够访问其他用户的食谱(如果其他用户允许)。我使用 Firebase Cloud Firestore 作为数据库。因此,如果当前用户是请求的用户 usersAllowedToRead 集合的一部分,那么他们还可以访问其他用户的食谱。

  match /databases/{database}/documents {
   
    match /users/{userId} {
      // Allow the user to read and write their own document
      allow read, write: if request.auth != null && request.auth.uid == userId;

      match /recipes/{recipeId} {
        // Allow read access if the user is authenticated and either is the user document owner
        // or is listed in the 'usersAllowedToRead' subcollection of the user document
        allow read: if request.auth != null && (request.auth.uid == userId || exists(/databases/$(database)/documents/users/$(userId)/usersAllowedToRead/$(request.auth.uid)));
        // Allow write access only if the user is authenticated and is the user document owner
        allow write: if request.auth != null && request.auth.uid == userId;
      }
    }  
  }

但我总是收到一条错误消息,指出访问被拒绝。当我在 firebase 规则游乐场中测试它时,即使当前用户存在于其他用户的 usersAllowedToRead 集合中,存在也会评估为 false。

这条路径存在于我的数据库中:

/users/VJ1DcW.../usersAllowedToRead/MmrFH...
但是当我执行 get 调用时,exists 方法的计算结果为 false,我不明白为什么。

flutter firebase google-cloud-firestore firebase-security
1个回答
0
投票

我的猜测是,您的查询(您没有包含在问题中)正在尝试读取用户的整个

recipes
子集合,这将不起作用,因为 Firebase 安全规则不会过滤数据。相反,规则引擎只是确保来自客户端 SDK 的任何数据访问都符合您为该数据设置的规则。

您当前的代码在您请求单个文档时工作,但不适用于列表样式查询,因为Firestore实际上无法以可扩展的方式检查所有潜在文档的数据。对于列表样式的调用,您将使用查询,并且必须确保您的查询满足规则的条件,这对于您当前的规则来说是不可能的 - 因为无法编写检查的查询与规则中的

exists
调用相同。

因此,您需要更改数据结构,以确保查询所需的所有数据都位于查询实际返回的文档内。完成此操作后,您的规则还可以过滤该数据 - 一旦规则和查询匹配,代码就会起作用。

© www.soinside.com 2019 - 2024. All rights reserved.