问题描述
所以我目前对所有用户都有两个角色:isAdmin和isReader.
So I currently have two roles for all users: isAdmin and isReader.
允许管理员读取和写入数据,而允许读取器读取数据.
An Admin is allowed to read and write data and an Reader is allowed to read data.
某人创建帐户时,他无权.甚至没有isReader
.只有管理员可以更改规则.
When someone creates an account he has no rights. Not even isReader
. Only an Admin can change rules.
这是我打算这样做的方式:
This is how I planned to do it:
一旦有人创建了帐户,我将在Users
集合中创建一个文档,如下所示:
Once someone creates an account I create an Document in the Users
Collection like this:
uid: user.uid,
email: user.email,
role: {
isAdmin: false,
isReader: false,
}
每次登录时,我都会更新电子邮件"和"uid
",但保持"role
"不变.为了确保这种行为,我有以下规则:
On each login I update 'email' and uid
but keep role
untouched. To secure this behaviour I have these rules:
match /Users/{userId} {
allow read: if isOwner(userId) || isAdmin();
allow create: if request.resource.data.hasAll(['uid', 'email', 'role']) && request.resource.data.role.isAdmin == false && request.resource.data.role.isReader == false;
allow update: if resource.data.role == null || isAdmin();
}
function isAdmin() {
return getUserData().role.isAdmin == true;
}
我认为我有2个错误:
-
由于某些原因,
data.hasAll(['uid', 'email', 'role'])
无法正常工作.当我删除此部分时,create
规则按计划工作.
for some reason the
data.hasAll(['uid', 'email', 'role'])
does not work. When I remove this part thecreate
rule works as planned.
resource.data.role == null
不起作用.我打算检查数据是否包含role
的任何更新,因为我不允许,因为它不是来自管理员.但是由于某种原因,它不起作用.
resource.data.role == null
does not work. I intend to check if the data contains any updates for role
because I can't allow it is it doesn't come from an Admin. But for some reason it does not work.
有人知道我在做什么错吗?我的策略还可以保存吗?或者有人可以破解"自己的读者或管理员权限吗?
Any Ideas what I'm doing wrong? Also is my strategy save or is there a way someone could "hack" himself Reader or Admin rights?
推荐答案
对于自定义身份验证声明,这似乎是一个很好的用例.您可以在受保护的环境中为用户设置特定的角色,如代码实验室.以下是在服务器中设置自定义声明的示例.您甚至可以为此使用Cloud Functions.我建议您检查一下Codelab的完整代码,以便了解如何确保不仅有人可以请求向其用户添加自定义声明.
This looks like it may be a good use case for custom auth claims. You can set specific roles on a user within a secured environment, as shown in this codelab. Below is an example of setting a custom claim in your server. You can even use Cloud Functions for this. I recommend you check out the full code of the Codelab so you can see how to ensure not just anyone can request custom claims be added to their user.
admin.auth().setCustomUserClaims(uid, {Admin: true}).then(() => {
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
});
然后,您可以在安全规则中检查用户的那些角色.
Then you can check for those roles on the user in your security rules.
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{userId} {
allow read: if request.auth.token.Owner == true || request.auth.token.Admin == true;
allow create: request.auth.uid == userId &&
request.resource.data.uid == request.auth.uid &&
request.resource.data.email != null;
allow update: request.auth.uid == userId || request.auth.token.Admin == true;
}
}
}
请注意,由于不再需要有关角色"的所有规则,因此已将其删除.如果您对实现有疑问,请告诉我,因为这是一个普遍的问题,因此我想在此方面做更多的介绍.
Notice all the rules about "role" have been removed because they're no longer needed. Let me know if you have questions about implementation because I'm trying to make some more content around this since it's such a common problem.
这篇关于Firestore规则:验证数据没有字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!