Firestore安全规则:仅当新文档ID与用户ID相同时,才允许用户创建文档 [英] Firestore Security Rules: Allow User To Create Doc Only If New Doc ID is same as User ID

查看:41
本文介绍了Firestore安全规则:仅当新文档ID与用户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屋!

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