Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict Firebase users by email

I have a client that would like to be able to make a list of restricted emails that can access the data. So anyone else coming to the app can't read/write any data at all ( ideally can't even log in but I don't think that's possible with Firebase? ). Any ideas on how to go about this? I had thought of having an array of accepted emails and checking whether their email existed in the security rules but that didn't seem to work. I had the following in the database:

"validEmails": ["[email protected]"]

and then in the security rules:

".read": "root.child('validEmails').val().indexOf(auth.token.email) > -1"

But it looks like you can't use indexOf in those security rules.

Maybe I need to have a list of acceptable emails, and then when a user signs up it checks whether they're in that list and adds their UID to an accepted list? I guess I could do this through a cloud function or something?

Any help would be much appreciated.

Cheers

like image 215
Matt Sanders Avatar asked Sep 04 '17 05:09

Matt Sanders


3 Answers

Have the list of allowed user's emails in the database:

"whitelist": {
   "fred@gmail%2Ecom": true,
   "barney@aol%2Ecom": true
 }

Since periods are not allowed in keys, you need to escape strings with periods before storing them.

Then in the database rules:

{
    "rules": {
        "whitelist": {
            ".read": false,
            ".write": false
        },
        ".read": "root.child('whitelist').child(auth.token.email.replace('.', '%2E')).exists()",
        ".write": "root.child('whitelist').child(auth.token.email.replace('.', '%2E')).exists()"
    }
}

User's email is accessible via auth.token.email. You need to escape the dots (. -> %2E) and check if the key exists on the whitelist.

These rules don't allow anyone read or write access to the /whitelist section of the database. Modification is only possible via firebase console.

like image 154
rzymek Avatar answered Sep 30 '22 11:09

rzymek


Thanks guys, what I ended up doing was having a list of acceptable emails:

{
    "validEmails": ["[email protected]"],
    "validUsers": {}
}

and then have a cloud function run to check when a user signed up if their email was in the valid email list. If it was then it added them to the valid users list and if not it deleted the newly created user. I also set up data rules so that only users within validUsers could access the data.

The front-end then handled the redirection etc for invalid users.

like image 29
Matt Sanders Avatar answered Sep 30 '22 10:09

Matt Sanders


Once you enable the authentication module of Firebase I believe you can't restrict it to email addresses or domains. However you could secure your database another way. If your users are already registered and you know their uid, then you can restrict read and write access based on these.

Lets pretend you have an acl object in the database, you can list the users and their uid with their read/write permissions.

These rules will check each request and only allow authorised users to access the data.

{
  "acl": {
    [
      {
        "uid: "abc123"
        "canRead": true,
        "canWrite": true
      },
      {
        "uid": "def456",
        "canRead": true,
        "canWrite": false
      }
  },
  "secure": {
    ".read": { root.child('acl').child(auth.uid).child('canRead').val() == true }
    ".write": { root.child('acl').child(auth.uid).child('canWrite').val() == true }
  }
}
like image 39
sketchthat Avatar answered Sep 30 '22 10:09

sketchthat