Firebase security per user

369 views Asked by At

I'm working on a site, using firebase
The security was:

{
  "rules": {
    "users": {
      ".read": true,
      ".write": true
    }
  }
}

So everyone can add their info, but none can access the main part.
But when someone now types this in the console:

ref = new Firebase("https://xxx.firebaseio.com/users");
ref.createUser({
        email: email,
        password: password
}, function(error, userData) {});
ref.authWithPassword({
        email: email,
        password: password
    }, function(error, authData) {));
ref.remove();

all userdata will be removed. All users have their own uid (e.g. simplelogin:58) and storageID (e.g. -Js18LFoT0SmFi2Iq4GP)
could I maybe do something with those? I really don't want anyone to be able to remove all of my user data, but I need to let the users edit their own info, and to remove their account when they'd like to.

Here's some of my code:

function register() {
    var ref = new Firebase("https://fiery-heat-xxx.firebaseio.com/");
    ref.createUser({
        email: email,
        password: password
    }, function(error, userData) {
        if (error) {
            alert("Error creating user: " + error)
        } else {
            console.log("Successfully created user account with uid:", userData.uid);
            var uid = userData.uid


            var usersRef = new Firebase("https://fiery-heat-xxx.firebaseio.com/users/" + uid)
            var newUser = usersRef.set({
                faveShow1: "",
                faveShow2: "",
                faveShow3: "",
                faveShow4: "",
                faveShow5: "",
                faveShow6: "",
                faveShow7: "",
                faveShow8: "",
                faveShow9: "",
                faveShow10: "",
                uid: uid
            });
            //var key = newUser.key();
            //console.log(key)
            login();
        }
    });
}

function login() {
  clear();
    var ref = new Firebase("https://fiery-heat-xxx.firebaseio.com/");
    ref.authWithPassword({
        email: email,
        password: password
    }, function(error, authData) {
        if (error) {
            alert("Login Failed!" + error);
        } else {
            console.log("Authenticated successfully with payload:", authData);

            thisAuthData = authData.uid;
            var usersRef = new Firebase("https://fiery-heat-xxx.firebaseio.com/users/" + thisAuthData);

            usersRef.on("value", function(snapshot) {
                for (var i = 0; i < 1; i++) {
console.log(snapshot.val())
                    if (true) {
                        globalAuthData = snapshot.val();
                        //globalKey = amount;
                        var SS = snapshot.val()
                        show1 = SS.faveShow1;
                        show2 = SS.faveShow2;
                        show3 = SS.faveShow3;
                        show4 = SS.faveShow4;
                        show5 = SS.faveShow5;
                        show6 = SS.faveShow6;
                        show7 = SS.faveShow7;
                        show8 = SS.faveShow8;
                        show9 = SS.faveShow9;
                        show10 = SS.faveShow10;
                        //...//




                    }
                }

            }, function(errorObject) {
                alert("The read failed: " + errorObject.code);
            });




        }
    });
}

function removeUser() {
  clear();
    var ref = new Firebase("https://fiery-heat-xxx.firebaseio.com/");
    var refSer = new Firebase("https://fiery-heat-xxx.firebaseio.com/users/" + thisAuthData)


    ref.removeUser({
        email: email,
        password: password
    }, function(error) {
        if (error === null) {
            alert("User removed successfully");
            refSer.remove();
            logoff();
        } else {
            console.log("Error removing user:", error);
        }
    });
}

function edit() {
  clear();
    var fredNameRef = new Firebase('https://fiery-heat-xxx.firebaseio.com/users/' + thisAuthData);
    var onComplete = function(error) {
        if (error) {
            console.log('Synchronization failed');
        } else {
            console.log('Synchronization succeeded');
            console.log(thisAuthData);
            console.log(globalAuthData);
            login();
        }
    };
    if (document.getElementById("form1").value != "") {
        var show1 = document.getElementById("form1").value;
    }
    var show2 = document.getElementById("form2").value;
    var show3 = document.getElementById("form3").value;
    var show4 = document.getElementById("form4").value;
    var show5 = document.getElementById("form5").value;
    var show6 = document.getElementById("form6").value;
    var show7 = document.getElementById("form7").value;
    var show8 = document.getElementById("form8").value;
    var show9 = document.getElementById("form9").value;
    var show10 = document.getElementById("form10").value;


    fredNameRef.update({
        faveShow1: show1,
        faveShow2: show2,
        faveShow3: show3,
        faveShow4: show4,
        faveShow5: show5,
        faveShow6: show6,
        faveShow7: show7,
        faveShow8: show8,
        faveShow9: show9,
        faveShow10: show10,
    }, onComplete);

}

function logoff() {
  clear()
    var ref = new Firebase('https://fiery-heat-xxx.firebaseio.com/')
    ref.unauth();
    //...//
    }
}

and my securety rules:

{
  "rules": {
    "users": {
      "$user_id": {
         ".write": "$user_id === auth.uid"
      },
     ".read": true
    }
  }
}

But I can't register or update right now...

1

There are 1 answers

19
nstock On

To make sure a user's information can only be edited by that user, you want to use auth.uid.

https://www.firebase.com/docs/web/guide/understanding-security.html

The most important built-in variable is auth. This variable is populated after your user authenticates. It contains data about them and auth.uid, a unique, alphanumeric identifier that works across providers. The auth variable is the foundation of many rules.

{
  "rules": {
    "users": {
      "$user_id": {
        ".write": "$user_id === auth.uid"
      }
    }
  }
}

To make it a little more clear, auth.uid refers to the currently logged in user, and $user_id refers to the location in database. The $ points to the $location rule variable:

https://www.firebase.com/docs/security/api/rule/path.html

{   "rules": {
    "users": {
      "$user": {
        ".read": "auth.uid === $user",
        ".write": "auth.uid === $user"
      }
    }  
  } 
}

When a user authenticates to a Firebase app, three things happen:

  • Information about the user is returned in callbacks on the client device. This allows you to customize your app's user experience for that specific user.

  • The user information returned contains a uid (a unique ID), which is guaranteed to be distinct across all providers, and to never change for a specific authenticated user. The uid is a String that contains the name of the provider you're authenticating with, followed by a colon and a unique id returned from the provider.

  • The value of the auth variable in your app's Security and Firebase Rules becomes defined. This variable is null for unauthenticated users, but for authenticated users it is an object containing the user's unique (auth.uid) and potentially other data about the user. This allows you to securely control data access on a per-user basis.