在Firestore中安全保存数据 [英] Securely saving data in Firestore
问题描述
Firestore文档显示
The Firestore documentation shows examples of how to secure data using Firestore security rules based on the request.auth.uid
field. These typically look something like this:
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Only the authenticated user who authored the document can read or write
allow read, write: if request.auth.uid == resource.data.author;
}
}
}
这很合理.
我不了解(而且似乎未在任何地方显示)的是如何安全地设置 resource.data.author
字段.
What I don't understand (and doesn't appear to be shown anywhere) is how to set the resource.data.author
field securely.
显然,这不能仅仅基于客户端,因为任何经过身份验证的用户都可以篡改将其作者设置为任何值的请求.
Obviously that can't just be based from the client because then any authenticated user can tamper with the request to set their author to any value.
我想也许我们应该使用CloudFunctions来设置该字段,但是
I thought maybe we are supposed to use CloudFunctions to set that field but at the moment this doesn't work.
{
user: "alice",
content: "I think this is a great story!"
}
当然必须有一种防篡改的方式在此处设置用户字段-否则任何用户都可以使自己的评论似乎来自其他任何人.这似乎很糟糕.
Surely there must be a tamper-proof way to set the user field there - otherwise any user can make their comments appear to be from anyone else. This seems bad.
在Firestore示例网络应用中,似乎设置了客户端上的userId字段,我认为它正在执行
In the Firestore example web app, it seems to set the userId field on the client side and I think it is doing the same in the Android version.
我想念什么?
@imjared指出,此规则表示 user:"alice"
中的"alice"实际上是一个uid,因此我认为这是安全的.
as @imjared points out this rule implies that 'alice' in user: "alice"
is actually a uid, so I think this is safe.
我知道我错过了一些东西.
I knew I was missing something.
match /comments/{comment} {
allow read: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
['owner', 'writer', 'commenter', 'reader']);
allow create: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
['owner', 'writer', 'commenter'])
&& request.resource.data.user == request.auth.uid;
推荐答案
当用户将文档写入Firebase时,他们确实可以为所需的 author
字段发送任何值.但是他们无法设置 request.auth.uid
.最后一点对于确保所有(读取和写入)访问均得到授权至关重要.
When the user writes a document to Firebase, they can indeed send any value for the author
field they want. But there's no way for them to set request.auth.uid
. This last bit in crucial to ensure all (read and write) access is authorized.
您共享的第一个规则片段实际上有两个规则,暂时将它们分开可能会更容易:
The first rules snippet you shared actually has two rules, and it might be easier to separate them out for a moment:
allow read: if request.auth.uid == resource.data.author;
allow write: if request.auth.uid == resource.data.author;
仅当请求中特定于 author
与 request.auth.uid
相同时, write
规则才允许操作.由于不能伪造 request.auth.uid
,并且 author
的值只有相同时才会被接受,因此只有 author
字段是当前已验证用户的字段.
The write
rule only allows the operation when the author
specific in the request is the same as the request.auth.uid
. Since request.auth.uid
can't be spoofed, and the value of author
will only be accepted if it is the same, the write operation is only allowed if the author
field is that of the currently authenticated user.
实际上,后一条规则通常写为:
In fact, that latter rule is more regularly written as:
allow write: if request.auth.uid == request.resource.data.author;
使用 request
的区别在于,它明确引用了 write
请求中的文档( resource
).无论我们使用 resource
还是 request.resource
,结果都是相同的,但是我发现在考虑 request
在这里.
The difference when using request
is that it explicitly refers to the document (resource
) that is in the write
request. The result is the same here whether we use resource
or request.resource
, but I find it easier to see how security works when thinking of the request
here.
这篇关于在Firestore中安全保存数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!