security rules to allow update of specific fields

て烟熏妆下的殇ゞ 提交于 2020-05-09 06:42:48

问题


I am new to security rules. I have to write security rule to prevent a user to update a document except one field.

lets say i have a doc

{ field1 : one, field2 : two, field3 : three, . . . fieldn : n }

the user logged in should be able to update only field2. using firestore security rules.


回答1:


There is no explicit way in security rules to validate the update that is happening. But what you can do is validate the data in the document before and after the write operation. By comparing those two, and by knowing what fields the document can contain, you can ensure that only specific fields can be updated.

I often use this little helper function in my security rules:

function isUnmodified(key) {
  return request.resource.data[key] == resource.data[key]
}

As its name implies, it ensures that a certain key/field is not modified in this write request. For example, this rule then only allows a user to update their profile document, as long as they don't modify the name field (unless they're an admin):

allow update: if isAdmin(request) || 
  (request.auth.uid == uid && isUnmodified(request, resource, 'name'));

I also have this helper function, which checks whether a specific field exists:

function isNotExisting(key) {
  return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
}

This is important, because sometimes you want to allow a field to be only written once, or only allow it to be updated if it already exists. Sometimes I use isNotExisting for that, but I find myself more these days using the more granular actions (create, update) over the aggregate write rule.

Finally, you can require certain fields, as in this creation rule:

  allow create: if request.auth.uid == uid &&
    request.resource.data.keys().hasOnly(['lastIndex', 'lastUpdated']) &&
    request.resource.data.keys().hasAll(['lastIndex', 'lastUpdated']) 

So a user can only create a profile document if they specify lastIndex and lastUpdated fields. If they specify any additional fields, or specify fewer fields, the creation will be rejected.

Now with this knowledge, we can go back to your requirement, and see how to implement it. As said before, you will need to make a statement on each individual field, without having a wildcard in there. So if your document has three fields (field1, field2, and field3), which must all exist, and the user can only update field2, that'd be something like:

allow update: if request.resource.data.keys().hasAll(['field1', 'field2', 'field2']) &&
  isUnmodified('field1')) && isUnmodified('field3'));


来源:https://stackoverflow.com/questions/58143344/security-rules-to-allow-update-of-specific-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!