最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firebase security rules: restrict write only to this uid, except for a couple of fields - Stack Overflow

programmeradmin3浏览0评论

In Firebase I have a users "node", which looks like:

users: {
  someUid: {
    username: 'someUsername'
    activeConversations: {},
    profile_picture: ''
    ... lots of other children
  },
  ...
},
anotherNode: {

},
... hundreds of other nodes

My rules right now:

{
  "rules": {
    ".read": true,
    ".write": true,
    "users": {
      ".indexOn": [
        "username"
      ]
    },
    "friendRequests": {
      ".indexOn": [
        "timeSent"
      ]
    }
  }
}

What I want to do is restrict child's access in the users "node" only to the client who owns the child. So for instance, the someUid child should only be writeable by the client with uid someUid. Other "node" like anotherNode can be writeable / readable by any logged-in client. Also, any logged-in client should be able to write on profile_picture and activeConversations in the users doc.

How can I achieve that without having to put a read/write rule on every single node?

Thank you

In Firebase I have a users "node", which looks like:

users: {
  someUid: {
    username: 'someUsername'
    activeConversations: {},
    profile_picture: ''
    ... lots of other children
  },
  ...
},
anotherNode: {

},
... hundreds of other nodes

My rules right now:

{
  "rules": {
    ".read": true,
    ".write": true,
    "users": {
      ".indexOn": [
        "username"
      ]
    },
    "friendRequests": {
      ".indexOn": [
        "timeSent"
      ]
    }
  }
}

What I want to do is restrict child's access in the users "node" only to the client who owns the child. So for instance, the someUid child should only be writeable by the client with uid someUid. Other "node" like anotherNode can be writeable / readable by any logged-in client. Also, any logged-in client should be able to write on profile_picture and activeConversations in the users doc.

How can I achieve that without having to put a read/write rule on every single node?

Thank you

Share Improve this question edited May 20, 2017 at 9:21 Dan P. asked May 16, 2017 at 10:47 Dan P.Dan P. 1,7754 gold badges29 silver badges57 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7 +100

I think @Bradley Mackey was nearly there but just needed a small tweak.

{
  "rules": {
    "users": {
      ".indexOn": ["username"],
      // wildcard, matches any node under 'users'
      "$someUid": {
        "$other" : {
          ".read": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid", 
          ".write": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid", 
        }
      }
    },
    "$anythingelse": {
      ".read": "auth != null",
      ".write": "auth != null",
    }
  }
}

The ".validate": field ensures that a field matches a certain format. The read and write here should give everyone read and write access if the field is profile_picture or activeConversations, and give the user access to everything else.

EDIT:

I added in another rule that would allow read-write access to any signed in user to any of the non-users nodes.

Having ".read": true, ".write": true at the root of your database is a very bad idea. Literally anyone could just wipe your entire database or insert any data at any time. This is because .read and .write rules cascade, so if you have them evaluating to true at some node, the person has permission for all children of that node as well.

Luckily more secure rules, like the rules you are proposing, are easy to implement. I'm assuming that someUid is equal to the users auth.uid you can do:

{
  "rules": {
    "users": {
      ".indexOn": ["username"],
      // wildcard, matches any node under 'users'
      "$someUid": {
        ".read": "auth != null",
        ".write":"auth != null",
        "$other" : {
          ".validate": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid" // only that own user can change their username
        }
      }
    }
  }
}

I've omitted your friendRequests node, because I'm not sure what security rules you'd like for that, but I hope this is enough to get you started.

The Firebase docs cover this stuff very well.

As per the firebase documentation, you can restrict the access permission at user level and data level

For example,

    // These rules grant access to a node matching the authenticated
    // user's ID from the Firebase auth token
    {
      "rules": {
        "users": {
          "$uid": {
            ".read": "$uid === auth.uid",
            ".write": "$uid === auth.uid"
          }
        }
      }
    }

Also you can restrict the read write permission in data level,

{
  "rules": {
    "messages": {
      "$message": {
        // only messages from the last ten minutes can be read
        ".read": "data.child('timestamp').val() > (now - 600000)",

        // new messages must have a string content and a number timestamp
        ".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
      }
    }
  }
}

Go through these firebase official documentation, https://firebase.google./docs/database/security/quickstart https://firebase.google./docs/database/security/user-security https://firebase.google./docs/database/security/securing-data

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论