javascript - 设置 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
解决方案
这是满足您要求的示例安全规则集。
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
的保存时,才能读取和写入下的文档。uid
uid
下users
的文档只有当它们的文档 id 与发送的请求相同时才能被读取和写入uid
。
isSignedIn()
函数检查请求是否被授权。
isUser(id)
函数检查 id 是否与授权请求的 uid 匹配。
isUserOwner()
函数检查文档的 uid 是否与授权请求的 uid 匹配。
推荐阅读
- ios - 如何在 CloudKit 中删除订阅
- c# - ASP.NET Core Web API 和 Jaeger - 我可以更改顶级 Span 名称吗?
- c# - WPF Window:调整窗口时自动调整窗口中的元素大小/调整元素
- postgresql - PostgreSQL:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换
- sql-server - 如何在 SQL Server 的 select 语句中的计算值中创建生成的序号?
- .net - 如何使用 Google.Cloud.Storage.V1 执行 HEAD 操作
- ruby - 如何在三元条件下使用“#redirect to '/path'”方法?
- nearprotocol - 用户生成的除主公钥以外的公钥
- javascript - 从函数调用的 api 在 VueJs 中总是返回一个 promise 对象
- mysql - MySQL插入忽略:是否可以判断哪个插入失败?