I need to implement chatting for a mobile app that talks to my own server, so the registered user information is on my own server. So, if I use firebase real-time database for chatting, how do I write the security rules like these:
".read": "auth != null", ".write": "auth != null"
So the scenario is, my user's information are on my own server, in my own database. I want to use firebase to implement a chat
How do I write the database rules that prevents anyone from reading the messages from database (by hitting the URL maybe ?)
Yours is precisely the scenario that Firebase Custom Authentication was made for.
On your server you authenticate your user against your own user database, then you mint a JSON Web Token with the information about that user that you want Firebase to know. At the very least the token should contain a uid, but it may contain more information that you can then access in your security rules. Once you've created the JWT, return it to your user.
In your app, you then use the JWT to sign in with Firebase. For example on Android that means, you'll call the FirebaseAuth.signInWithCustomToken() method.
For more information see the Firebase Database Server documentation.
Related
I am new to Firebase. Recently I registered my web-app and my android app in my firebase project. I have a Realtime Database in my project where the following rules are set:
{
"rules": {
".read": "auth !== null",
".write": "auth !== null"
}
}
I just got an email today from firebase saying that my database is insecure as any authenticated user can modify it. So my question is what rules do I set in my database such that only some users registered in my firebase project (i.e., my web app and my android app) can access it?
The simplest way to allow only users of your app to access the data, is to implement Firebase App Check in the application and then enforce that for the Realtime Database.
This topic has been covered quite a few times before, so I recommend also checking out:
Locking down Firebase DB access to specific apps
Firebase rules that supports only requests from my apps
hi i'm working with angular and firebase, in a web app, if i open the browser tools on console, i can see the connection keys to my firebase it's very bad.
the rules in firebase is the solution at this problem. but all answers i found are based on auth of users and on my web app is not necesary auth. how i can set rules so that only my web app can read and write without users auth. because if i create another projec and i use the same keys i can map the database and anyone can update the data thanks
p.d. my rules actually are read=true and write=true, this allows anyone to read and write.
{
"rules": {
".read": "true != null",
".write": "true != null"
}
}
P.d. my web app is hosted in Firebase Hosting thanks again
This is not possible with security rules. If you don't restrict usage with Firebase Authentication, that means anyone with an internet connection can read and write your database.
I was looking for simple authentication mechanism for multiple users in Firebase real-time database. For ex: I don't want all millions of users to login using email and password to access Firebase real-time.
I came across creating custom token from the below documentation.
https://firebase.google.com/docs/auth/admin/create-custom-tokens
I want to understand clearly about that. Is this something that helps to authenticate multiple users (grouped as one) programmatically via custom token instead of each user has to authenticate using email address and password? or This is different from what I thought?
Please advise.
No, custom tokens are used when you have your own database of users that have already signed into your existing service with some other form of credentials that you provide.
If you don't have your own database of users, custom tokens won't help.
Also, there is no such thing as "grouping" users for the purpose of authentication using Firebase Authentication. Each user has their own distinct identity with their own credentials that are dealt with independently of each other.
Custom tokens are used when you have your own authentication service but want to allow your users to access Firebase services. If you want your users to be able to use the database without an email and password, you can use a provider such as Google or use Anonymous authentication, which is when the user is logged in and can access the database, but don't have to prove that they're themselves. You can always add them as an actual user later.
To allow authenticated users to access the database, you can use these rules:
// These rules require authentication
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Database Rules Docs
There is a difference between when a user signs in (authentication) and when they gain access to your database (authorization).
There is no way to prevent users from authenticating with Firebase Authentication's built-in providers that you've enabled in the Firebase console. But it's quite easy to only allow specific users access to the data in your database with Firebase's server-side security rules.
For example, if you only want specific users access, you can set up a whitelist of their UIDs:
allowedUsers
uid1: true,
uid2: true,
uid3: true
Now you can write a simple security rule that only allows users in this list to read your database:
{
"rules": {
".read": "root.child('allowedUsers').child(auth.uid).exists()"
}
}
Assuming users don't create an account and only use device token, one can have this structure:
users/${device_token}/posts
Now, how can you protect that each user can only access their own posts?
I have used this in the past: .write: "$uid === auth.uid" when I had each user create an account and log in. How can I get a similar result when users don't create an account and just use device token?
Only the currently authenticated Firebase Authentication user is available in Firebase Database security rules. Since the FCM token is not part of a user object, the FCM device token is not available in the Firebase Database security rules.
So you will need to use Firebase Authentication to ensure that there is a current user. Luckily you can use anonymous authentication to ensure there is a current user without the user having to explicitly sign in. This makes the auth.uid in your security rules work again.
The next step is to associate the user profile with the FCM device token. I can quickly think of two ways to do that:
Store the token in the user's profile as an additional claim.
Store the token in the database associated with the UID.
To store the token in the user's profile, you'll need to use the Firebase Admin SDK. This means this that you need to run this code on a trusted environment, such as a server you control or Cloud Functions. Once you have this, setting a custom claim is as easy as:
admin.auth().setCustomUserClaims(uid, {deviceToken: "....."});
And you'd use it in your security rules as:
".write": "auth.token.deviceToken === '...'",
Read the documentation for more info as there are some limits to what you can set.
A more flexible, but more cumbersome, approach is to store the token in the database. To do this you add a new top-level node to the database, where you store the token for each user:
tokens
$uid: "..."
You'll want to secure this part of the database so that users can only write their own token.
After that you can access this node in the other rule to check their token. For example:
".write": "root.child('tokens').child(auth.uid).val() === $token".
My problem is my project has 2 application. One application just run in a specific mobile device which we known, it interact with firebase without authenication. The another is run in many mobile devices, it must sign-in into firebase to communicate each other.
So, what I want to do is how to configure database rule in firebase to 2 app can use the same the database? Thank everyone very much! Appologize for my bad english.
You cannot secure database access to allow a specific app or a specific device. See How to prevent other access to my firebase.
But a device can easily be mapped to belong to a specific user, if you use Firebase Authentication. You could even use anonymous authentication if you don't want to require that the user signs in. With Firebase Authentication each user has a unique user id (UID in Firebase terms). And when you know the UID for the user, you can secure access to the database based on that UID.
An example from a recent project:
{
"rules": {
".read": true,
".write": "auth != null &&
root.child('config/whitelist').child(auth.uid).exists()"
}
}
So here, we allow writing if the signed-in user's UID is present under a node /config/whitelist. E.g.
config
whitelist
"jn0BrHQqUEYSjqvqfqzbJTMOlZ82": true
"ytEtWqOfLkRk3OUjTKBtZnTehZc2" true