问题
I have this JavaScript code where users sign in to my app using their google account.
//firebase db congifurations
const config = {
apiKey: "my_api_key",
authDomain: "my-app.firebaseapp.com",
projectId: "my-app",
databaseURL: "https://my-app.firebaseio.com",
};
//signin callback implemented using - https://developers.google.com/identity/sign-in/web/sign-in
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
let fullName = profile.getName().split(" ");
let userName = profile.getEmail().replace(/@.*$/, "");
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
this.database = firebase.database();
let userRef = this.database.ref("users/" + userName);
userRef.set({
firstName: fullName[0],
lastName: fullName[1],
displayPicture: profile.getImageUrl(),
});
}
When I execute this code, put a debugger at let userRef = this.database.ref("users/" + userName);
and try to run this on console:
userRef.set({
firstName: "Clutch",
lastName: "Prince",
displayPicture: "any_url_that_i_want_to_inject",
});
This one actually gets executed and my database gets affected. Is there a secure way of doing this?
My Realtime Database rules:
{
"rules": {
".read": true,
".write": true
}
}
回答1:
Firebase rules are the most important part.
No one except you can edit those. So make sure they are secure. You have .write: true
means anyone can write your database.
To prevent that you should have secure rules. You can check out this link for most of the rules combinations.
Looking at your issue, set the rules as follows:
{
"rules": {
"Users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Make sure you store all the users data in different nodes. Keep the node value as their UID. Then the above rules should be handy 🙂
Now users can edit or read only their information. Even if they try to edit it via console, atleast you are keeping others safe. If it's a game, sure go ahead and add penalty if you spot them XD.
This can still allow users to edit atleast their information as stated earlier as well. So in case if you are storing some sort of a game statistics and how much resources the player has, then you need to block write access by doing this:
".write": false
Now this might confuse you that if write access is denied then how will players update their scores or how can one add the username in database.
For this, you need to rely on cloud functions. Whenever a new player creates an account, I run a cloud function which adds default level and other stuff. Here a code sample below:
export const onNewuserJoined = functions.auth.user().onCreate((user) => {
const newUserUID = user.uid
const newUserEmail = user.email
return Promise.all([
admin.database().ref(player_stats_path).set({ "Level": initLevel, "Cash": initCash}),
admin.database().ref(player_info_path).set({ "UID": newUserUID, "E-Mail": newUserEmail})
])
})
Now these player_stats_path
and player_info_path
will have read access only so no one can mess with it except for the cloud functions as the OVERRIDE any rules present. If you need to change the stats of someone when they complete a particular task or so, you will need to do it via cloud functions only. It's nice to have all game code in backend.
来源:https://stackoverflow.com/questions/61577553/how-to-prevent-access-to-firebase-realtime-database-from-browser-console