有关如何使用基于request.auth.uid
字段的Firestore安全规则保护数据安全的Firestore文档shows examples。这些通常看起来像这样:
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
字段。
显然,这不能仅基于客户端,因为任何经过身份验证的用户都可以篡改将其作者设置为任何值的请求。
我想也许我们应该使用CloudFunctions来设置该字段,但是at the moment this doesn't work。
在role based access example中,这种影响非常明显:
{
user: "alice",
content: "I think this is a great story!"
}
当然必须有一种防篡改的方式在此处设置用户字段-否则任何用户都可以使他们的评论似乎来自其他人。这似乎很糟糕。
在Firestore示例Web应用程序中,似乎设置了userId field on the client side,我认为它正在执行the same in the Android version。
我想念什么?
编辑:正如@imjared指出,该规则意味着user: "alice"
中的'alice'实际上是一个uid,因此我认为这是安全的。
我知道我错过了一些东西。
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;
答案 0 :(得分:0)
当用户将文档写入Firebase时,他们确实可以为所需的author
字段发送任何值。但是他们无法设置request.auth.uid
。最后一点对于确保所有(读取和写入)访问均得到授权至关重要。
您共享的第一个规则片段实际上有两个规则,暂时将它们分开可能会更容易:
allow read: if request.auth.uid == resource.data.author;
allow write: if request.auth.uid == resource.data.author;
仅当请求中特定的write
与author
相同时,request.auth.uid
规则才允许操作。由于无法伪造request.auth.uid
,并且author
的值只有在相同的情况下才会被接受,因此仅当author
字段是当前字段的值时才允许写操作经过身份验证的用户。
实际上,后一条规则通常写为:
allow write: if request.auth.uid == request.resource.data.author;
使用request
的区别在于,它明确引用了resource
请求中的文档(write
)。无论我们使用resource
还是request.resource
,这里的结果都是相同的,但是我发现在这里想到request
时更容易了解安全性。