设置 Firebase Firestore 安全规则,以便只有用户可以 CRUD 自己的数据,其他所有内容都将被忽略

Wil*_*iam 8 javascript firebase firebase-security

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

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

待办事项

todo:{
  title:"some titled",
  body:"we are the world , we are the children",
  uid:"2378y4c2378rdt2387btyc23r7y"  
}
Run Code Online (Sandbox Code Playgroud)

其他一些收藏

thing:{
  name:"some name",
  content:"Some content",
  whatever:"whu-eva",
  uid:"2378y4c2378rdt2387btyc23r7y"  
}
Run Code Online (Sandbox Code Playgroud)

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

我想知道如何为这个场景创建规则。

我现在正在仔细阅读文档,但我想我可以通过询问来节省一些时间。我没有该应用程序的特定角色。 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;
      }
    }
  }

Run Code Online (Sandbox Code Playgroud)

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

视频

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

cer*_*ner 9

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

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
    }

  }
}
Run Code Online (Sandbox Code Playgroud)

所有文件均不可公开访问。

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

下的文档todos只有在保存uid与发送请求的uid.

根据文件users,可以读取和写入仅当它们的文档ID是一样的所发送的请求的uid

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

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

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


klu*_*gjo 0

你正在寻找这样的东西

service.cloud.firestore {
  match /databases/{database}/documents {
    match /todos/{userId} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

match /todos/{userId}使userId变量在规则条件中可用

request.auth.uid与授权用户匹配uid