Proper authorization rules for protected content in firebase

10,035

You've done a good job of enumerating the options, and you're definitely on the right track. As you've discovered, there's no way to query based on security rules. This was done intentionally, since (depending on your security rules) this could be quite expensive (Firebase avoids complex queries in general for this reason).

So your method 3 is the exact right way to do this. Duplicating data for these sorts of situations is actually a very common practice. See Denormalizing Your Data is Normal for a blog post that goes into more detail on this.

You could also do method 1 with the duplicated document list. This is especially useful if you want to be able to "invite" somebody to a document just with a URL (that contains the secret ID). Or you could do a combination of the two (have some documents be "public but unlisted" and some be "private to invited friends" or whatever.)

Share:
10,035

Related videos on Youtube

abaker
Author by

abaker

Updated on June 17, 2022

Comments

  • abaker
    abaker about 2 years

    Is there a best practice approach to proper authorization rules for protected content in a firebase app

    • using firepad specifically
    • By protected content I mean where a user creates a document and only shares it with certain other users).
    • Also I need to be able to query firebase for all documents that i have access to (docs that I created and docs other users shared with me)

    Some of my research thus far:

    Method 1: Secret URL

    • I need to know the URL to be able to view/edit the document

    • Not real authorization, as any logged in user that has access to that URL could edit/modify it.

    • Cant index all the docs i have access to

    Method 2: Using firebase authorization rules to add users to a document and check if user is document.users before reading/writing.

    Taken From: Protected content in Firebase possible?

    {
    
    "documents": {
    
       "$documents_id": {
    
           // any friend can read my post
    
           ".read":  "auth.id === data.child('owner').val() || root.child('users/'+data.child.owner.val()+'/users/'+auth.id).exists()",
    
           // any friend can edit my post
           ".write": "auth.id === data.child('owner').val() || root.child('users/'+data.child.owner.val()+'/users/'+auth.id).exists()"
    
       },
    
       users:{
    
       // List of user.ids that have access to this document
    
       }
    
    }
    
    }
    

    Pros:

    • Proper authorization/authentication. Only authenticated users who have been granted access can view/edit.

    Cons:

    • Cannot query for all documents a user is allowed to edit (those that I own or have been shared with me) (Is this assumption correct?)

    Method 3: Firebase authorization rules (method 2), plus a redundant store of users with array of document_ids each users has access to. This user store would only be used to query all the documents a user has access to. ie:

    {
    "documents": {
       "$documents_id": {
           // any friend can read my post
           ".read":  "auth.id === data.child('owner').val() || root.child('users/'+data.child.owner.val()+'/users/'+auth.id).exists()",
           // any friend can edit my post
           ".write": "auth.id === data.child('owner').val() || root.child('users/'+data.child.owner.val()+'/users/'+auth.id).exists()"
       }
    },
    "users":{
        "$user":{
            ".read": "auth.id=$user.id",
            ".write": "auth.id=$user.id"
            "$documents":{
                // All the documents i have access to. This list gets ammended whenever I am granted/stripped access to a document.
            }
        }
    }
    }
    

    Pros:

    • Proper authentication/authorization

    Cons:

    • Duplicate data, have to deal with synchronization issues between two data stores. This just doesnt seem like a good idea.

    Method 4: Groups

    Using groups per Granting access to Firebase locations to a group of users

    • We have a group for every document in data store

    • Cant easily query firebase for all the docs a user can access

    Is there a better way to do this?

  • abaker
    abaker almost 11 years
    Thanks michael for that clarification. Will just have to be careful with keeping the important bits from each in sync.
  • Michael Lehenbauer
    Michael Lehenbauer almost 11 years
    Yeah. Though in a lot of cases you can pretty easily make your code robust against mismatches. For example, if you have a document in your list, but you get a permission denied error when you try to read its metadata, just hide it from the user. That way the security rules are the True Authority, and your personal document list is just a "hint" as to what you should have access to, and if it gets slightly out-of-sync, it doesn't matter. Of course if you can ensure they stay in sync, that's better, but it's not always 100% necessary. :-)