首页 > 解决方案 > 设置 Firebase Firestore 安全规则,以便只有用户可以 CRUD 自己的数据,而其他所有内容都被忽略

问题描述

我有一个应用程序,旨在使通过 Google 进行身份验证的用户只能访问他们自己的数据,而没有“社交”功能。我想知道以下标准的安全规则。

假设我有 5 个集合,其中一个称为“todos”,数据反映了其他集合,因为它有一个用于经过身份验证的用户 uid 的字段。典型的文档如下所示:

待办事项

todo:{
  title:"some titled",
  body:"we are the world , we are the children",
  uid:"2378y4c2378rdt2387btyc23r7y"  
}

其他一些收藏

thing:{
  name:"some name",
  content:"Some content",
  whatever:"whu-eva",
  uid:"2378y4c2378rdt2387btyc23r7y"  
}

我希望经过身份验证的 Google 用户能够对任何在 uid 字段中表示用户 uid 的数据进行 CRUD。我希望登录用户无法访问所有其他数据。

我想知道如何为这种情况创建规则。

我现在正在仔细研究文档,但我想我可以通过询问来节省一些时间。我没有该应用程序的特定角色。 https://firebase.google.com/docs/firestore/solutions/role-based-access

附带说明一下,Firebase 中的一项功能是自动将经过身份验证的 Google 用户 uid 绑定到他们登录时创建的文档吗?(我假设答案是否定的,并且我计划在我的应用程序中手动获取 uid 并在创建文档之前将其设置在客户端上)。

谢谢你。

更新

我尝试使用 Klugjo 在下面发布的代码。

当我尝试在模拟器中测试它时,我得到一个错误。

这是我的收藏和错误的屏幕截图。

在此处输入图像描述

在此处输入图像描述

这是我尝试过的其他东西: 在此处输入图像描述

根据我读过的所有内容,以下代码似乎应该可以工作 - 但事实并非如此。我已经补充了键“userId”来代替写在这篇文章顶部的对象数据中的“uid”。我更改了密钥以将其与 uid 区分开来。

service cloud.firestore {
  match /databases/{database}/documents {
    match /todos/{id} {
    allow read: if request.auth.uid == request.resource.data.userId;
    allow create, update, delete:
        if request.resource.data.userId == request.auth.uid;
      }
    }
  }

我创建了一个视频,我尝试在其中获取和创建文档。我认为我没有正确使用测试功能。

视频

https://www.youtube.com/watch?v=W7GZNxmBCBo&feature=youtu.be

编辑

当我使用硬编码的request.auth.uid. 在下图中,我将“测试”硬编码为request.auth.uid.

我现在的问题是,我真的很想知道如何在规则编辑器中对其进行测试,而无需对这些信息进行硬编码。

在此处输入图像描述

编辑

这是使用真实应用程序的问题的视频演示。

https://www.youtube.com/watch?v=J8qctcpKd4Y&feature=youtu.be

标签: javascriptfirebasefirebase-security

解决方案


这是满足您要求的示例安全规则集。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    match /users/{id}/{u=**} {
      allow read, write: if (isSignedIn() && isUser(id));
    }

    match /todos/{id}/{t=**} {
      allow read, write: if (isSignedIn() && isUserOwner());
    }

    match /{document=**} {
      allow read, write: if false;
    }



    function isSignedIn() {
      return request.auth != null;
    }

    function isUser(uid) {
      return uid == request.auth.uid;
    }

    function isUserOwner() {
      return getResourceData().uid == request.auth.uid;
    }

    function getResourceData() {
        return resource == null ? request.resource.data : resource.data
    }

  }
}

所有文件都无法公开访问。

其余的将根据已经保存在数据库中的数据和/或用户发送的数据来决定。关键点resource仅在从DB读取时request.resource存在,并且仅在写入DB时存在(从用户读取)。

只有当它们具有与发送请求相同todos的保存时,才能读取和写入下的文档。uiduid

users的文档只有当它们的文档 id 与发送的请求相同时才能被读取和写入uid

isSignedIn()函数检查请求是否被授权。

isUser(id)函数检查 id 是否与授权请求的 uid 匹配。

isUserOwner()函数检查文档的 uid 是否与授权请求的 uid 匹配。


推荐阅读