firebase - Firestore 安全规则 - 权限被拒绝

标签 firebase google-cloud-firestore firebase-security

我有一个用户集合,其中存储用户数据,例如姓名、电子邮件等,以及另一个用于被阻止用户的集合。我想允许用户阅读自己的文档以及他/她没有阻止的用户的文档。我已经实现了安全规则,但不知何故,用户甚至无法阅读自己的文档。有人可以帮忙吗?

用户集合

users { // name of collection
   a1 { // this is firebase id serving as document name
     name: "abc",
     email: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1d7c7f7e5d7a707c7471337e7270" rel="noreferrer noopener nofollow">[email protected]</a>
   }
   a2 { // this is firebase id serving as document name
     name: "efg",
     email: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d5b0b3b295b2b8b4bcb9fbb6bab8" rel="noreferrer noopener nofollow">[email protected]</a>
   }
   a3 { // this is firebase id serving as document name
     name: "hij",
     email: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a5cdcccfe5c2c8c4ccc98bc6cac8" rel="noreferrer noopener nofollow">[email protected]</a>
   }
   a4 { // this is firebase id serving as document name
     name: "klm",
     email: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="107b7c7d50777d71797c3e737f7d" rel="noreferrer noopener nofollow">[email protected]</a>
   }
}

阻止收藏

blocked { // name of the collection
    a1 { // name of the document
        a2 : 1, // this means a1 has blocked a2
        a4 : 1  // this means a1 has blocked a4
    }
}

安全规则

service cloud.firestore {
    match /databases/{database}/documents {
        match /users/{userId} {
            allow read: if request.auth.uid != null
            && get(/databases/$(database)/documents/blocked/$(request.auth.uid)).userId != 1;
        }

        match /blocked/{fid} { // blocked collection/fid == owner firebase id
            allow read: if request.auth.uid == fid;
        }
    }
}

代码

DocumentReference docref = Firestore.instance.collection("users").document(user.uid);
return docref.get();

最佳答案

在这种情况下,您需要以不同的方式处理 userId 变量。按照您编写的方式,规则是在用户被阻止文档的 Resource 对象中查找 userId 属性,而不是 userId 的值多变的。您可能还想为 get 调用提供合理的默认值。

同样,由于 get() 调用返回 Resource您需要使用 data 成员来获取 Map属性。

您可能还需要检查用户被阻止的文档是否确实存在,否则如果不存在,您的查询将会失败。

service cloud.firestore {
    match /databases/{database}/documents {
        match /users/{userId} {
            allow read: if request.auth.uid != null
                && (!exists(/databases/$(database)/documents/blocked/$(request.auth.uid)) ||
                    get(/databases/$(database)/documents/blocked/$(request.auth.uid)).data.get(userId,0) != 1);
        }

        match /blocked/{fid} { // blocked collection/fid == owner firebase id
            allow read: if request.auth.uid == fid;
        }
    }
}

以上内容应该允许(考虑到您在问题中定义的 /blocked):

  • 用户a1读取/users/a1
  • 用户a1读取/users/a3
  • user a2 读取 /users 中的任何文档

以上应该否认:

  • 全部写入
  • 用户a1读取/users/a2

我只在模拟器中对上述内容进行了一些松散的验证。强烈推荐您write extensive tests对于您最终使用的任何规则。

最后,请记住 security rules are not filters ,所以这实际上取决于您如何使用它 - 可能拒绝任何可能匹配的文档的查询将拒绝整个查询。您描述问题的方式(使用拒绝用户访问他们已阻止的其他用户的文档的规则)听起来像是您正在尝试过滤,而不是试图保护数据。

关于firebase - Firestore 安全规则 - 权限被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59055605/

相关文章:

javascript - 当 ionic 平台准备好时从 Angular 工厂返回

firebase - 如何访问Future方法中存在的回调函数的返回值。 Dart

由于 firebase-storage :11. 0.2 依赖性,Android 应用程序构建失败

java - 发生 Firebase 身份验证注册错误

java - Firebase Firestore 不允许存储 LinkedHashMap - Android

android - Firestore - 如何在数据库中自动递减整数值?

android - Firebase 远程配置安全

firebase - 使用 Firebase UID 作为二维码标签是否安全?

java - Firestore错误

javascript - 尝试使用 id 访问数据时,firebase 规则中的通配符不起作用