How do I lock down Firebase Database to any user from a specific (email) domain?

后端 未结 6 2004
灰色年华
灰色年华 2020-11-22 08:36

I have a small, personal Firebase webapp that uses Firebase Database. I want to secure (lock down) this app to any user from a single, specific domain. I want to authenticat

6条回答
  •  野性不改
    2020-11-22 09:27

    WARNING: do not trust this answer. Just here for discussion.

    tldr: I don't think it's possible, without running your own server.

    Here's my attempt thus far:

    {
      "rules": {
        ".read": "auth.provider === 'google' && root.child('users').child(auth.uid).child('email').val().endsWith('@foobar.com')",
        ".write": "auth.provider === 'google' && root.child('users').child(auth.uid).child('email').val().endsWith('@foobar.com')",
        "users": {
          "$user_id": {
            ".write": "auth.provider === 'google' && $user_id === auth.uid && newData.child('email').val().endsWith('@foobar.com')"
          }
        }
      }
    }
    

    I believe the above says "only allow people to create a new user if they are authenticated by Google, are trying to write into the database node for themselve ($user_id === auth.uid) and their email ends in foobar.com".

    However, a problem was pointed out: any web client can easily change their email (using the dev console) before the message is sent to Firebase. So we can't trust the user entry's data when stored into Firebase.

    I think the only thing we can actually trust is the auth object in the rules. That auth object is populated by Firebase's backend. And, unfortunately, the auth object does not include the email address.

    For the record, I am inserting my user this way:

    function authDataCallback(authData) {
      if (authData) {
        console.log("User " + authData.uid + " is logged in with " + authData.provider + " and has displayName " + authData.google.displayName);
        // save the user's profile into the database so we can list users,
        // use them in Security and Firebase Rules, and show profiles
        ref.child("users").child(authData.uid).set({
          provider: authData.provider,
          name: getName(authData),
          email: authData.google.email
        });
    

    As you might be able to imagine, a determined user could overwrite the value of email here (by using the DevTools, for examples).

提交回复
热议问题