在Firestore中安全保存数据 [英] Securely saving data in Firestore

查看:40
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆