Firestore安全规则:仅当新文档ID与用户ID相同时,才允许用户创建文档 [英] Firestore Security Rules: Allow User To Create Doc Only If New Doc ID is same as User ID
问题描述
用户首次登录时,我还需要调用一个函数,该函数在我的firestore用户集合中创建一个文档以存储其个人资料数据.使用Web SDK.
When users log in for the first time, I need to also call a function that creates a document in my firestore users collection to store their profile data. Using Web SDK.
(我以前使用的是带有Firebase函数的新的用户触发事件,但是它太慢了,无法等待冷函数启动).
(I was previously using a new user triggered event with firebase functions, but it was too slow to wait for a cold function to spin up).
安全规则要求
需要确保用户只能在文档ID与他们的用户ID相同的情况下创建文档(以防止用户创建其他文档).需要确保该文档尚不存在.
Needs to ensure that the user can only create a document if the document id is the same as their user id (to prevent the user from creating other docs). Needs to ensure that this doc doesn't already exist.
尝试-在模拟器中运行,而不是IRL
这些测试通过了模拟器,但没有通过IRL.
These tests pass in the simulator, but not IRL.
// Allow users to create a doc if the doc ID == their user id
allow create: if path("/databases/" + database + "/documents/users/" + request.auth.uid) == request.path;
OR
allow create: if /databases/$(database)/documents/users/$(request.auth.uid) == request.resource['__name__']
也尝试过此操作(同样,可以在模拟器中使用,但不能在IRL中使用)
Have also tried this (again, works in simulator, but not IRL)
match /users/{userId} {
// Allow users to read their own profile
allow create: if request.auth.uid == userId;
}
推荐答案
更新
我最近不得不更新规则集,这是因为对Firestore规则的工作方式进行了一些更改,并且更改了"getAfter"操作的方式.功能起作用.具体来说,我现在可以使用 request.resource 进行数据比较.无论如何,看来我现在可以用更简单的规则实现我的目标了,所以我想我会更新这个答案并分享.
Update
I recently had to update my rule set because of some changes to the way firestore rules worked, and changes in how the "getAfter" function works. Specifically, I am now able to use request.resource for data comarisons. Anyways, it appears that I can accomplish my goals with simpler rules now so I thought I'd update this answer and share.
- 仅当新文档ID与其用户ID相匹配时,用户才能创建文档.
- 用户不能声明自己为管理员",如果管理员"被阻止,则阻止创建/更新/写入请求.是一个字段(除非他们已经是管理员)
service cloud.firestore {
match /databases/{database}/documents {
// Allow users to create a document for themselves in the users collection
match /users/{document=**} {
allow create: if request.resource.id == request.auth.uid &&
!("admin" in request.resource.data);
}
// Allow users to read, write, update documents that have the same ID as their user id
match /users/{userId} {
// Allow users to read their own profile (doc id same as user id)
allow read: if request.auth.uid == userId;
// Allow users to write / update their own profile as long as no "admin"
// field is trying to be added or created - unless they are already an admin
allow write, update: if request.auth.uid == userId &&
(
!("admin" in request.resource.data) ||
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true // allow admin to update their own profile
)
// Allow users to read their own feeds
match /feeds/{document=**} {
allow read: if request.auth.uid == userId;
}
}
}
}
旧答案
所以我想出了一种解决方法.我还具有一些其他写入/更新条件,这些条件阻止用户更改其权限级别.这是由于某种原因,防止了任何创造".从发生.因此,我必须在创建和写入/更新规则中反映相同的条件.由于某些原因,这是必需的.
Old Answer
So I figured out how to do this in a workaround way. I also had some additional write / update conditions that prevent the user from changing their permission level. This was for some reason, preventing any "creates" from happening. So I had to mirror the same conditions in create, and the write / update rules. For some reason this was necessary.
第一部分,用于创建规则
- 仅允许经过身份验证的用户创建文档,仅在用户"页面中 (在用户设置过程中,系统会自动创建一个与用户ID相同的ID的文档).
- 不允许创建包含"admin"标签的文档.字段,这表明他们正在尝试获得管理员访问权限.
- 似乎无法在创建过程中验证文档的ID,因此下面提供了其他写入/更新规则
第二部分-读取,更新,写入
- 允许用户仅读取/写入/更新具有与其用户ID相同ID的文档(尝试创建具有其用户ID以外的ID的文档的用户将失败,还可以防止用户向其发送垃圾邮件客户端JS请求处理大量文档.)
- 不允许用户编写/更新其个人资料以包括"admin"字段
规则
service cloud.firestore {
match /databases/{database}/documents {
// Allow users to create documents in the user's collection
match /users/{document=**} {
allow create: if request.auth.uid != null &&
!("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
}
// Allow users to read, write, update documents that have the same ID as their user id
match /users/{userId} {
// Allow users to read their own profile (doc id same as user id)
allow read: if request.auth.uid == userId;
// Allow users to write / update their own profile as long as no "admin" field is trying to be added or created
allow write, update: if request.auth.uid == userId &&
!("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
}
}
}
PS 这一点都不直观,因此,如果有人有更好的解决方法,请发布它.另外,我真的希望Firestore 1.0推出后,它将为规则和规则文档带来一些巨大的改进.
PS This was not intuitive at all, so if someone has a better workaround, please post it. Also, I'm really hoping that once firestore 1.0 is out, it will bring with it some huge improvements to rules and rule documentation.
这篇关于Firestore安全规则:仅当新文档ID与用户ID相同时,才允许用户创建文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!