Do Firebase Security Rules affect user account creation & authentication? - firebase

I want to enable email & password authentication on my Firebase database. However I also want to strictly create accounts and authenticate users on the server rather than on the client. Can I simply set ".read" to false to prevent clients from creating accounts themselves? Or would I need to use custom authentication?

You cannot restrict the creation of Email & Password accounts on Firebase. You can only limit what data users can read and write. A user account that has no read/write access to any data is pretty useless.
With custom authentication you could indeed simply not mint a JWT for users that you don't want to create an account for. But as said: this doesn't improve data security, it just means that those user will get "you don't have an account" type message instead of "you don't have access to this data".

Related

Authenticate only "admin" users registered with Firebase Auth

I have an app that lets users sign in via email and password. The app has a feed with posts that need to be moderated. I have an admin react website that lets the moderators remove or keep posts. Right now any user can login and see the content, however I wanna make the login only available for admin users. I made my account "admin" using Admin SDK of Firebase.
I was thinking to make a Cloud Function which verifies whether the email is an admin and return true or false accordingly. Then authenticate the user normally using Firebase Auth. Is this secure enough?
If you've set a custom claim marking the user as an application administrator, you can check in your client-side code for the presence of that claim. You can then use the result of that to show the correct UI.
On the server/in the database security rules, you'll also want to check the presence of this admin claim before allow the user to access/modify the moderator data.
Note that none of these prevents the users from authenticating. Authentication in Firebase is nothing more than entering your credentials to prove that you are you. Granting access to resources based on who you are, known as authorization, is up to the application, hence including it in your client-side code, and server-side code or security rules.

Firestore rules for creating a user

I am new to firebase and trying to use firebase authentication, along with firestore database. It looks like all the security lies in rules we set, however I want to know the following:
Is it possible to apply rules based on user authentication without using firebase authentication system ?
How can I make sure that the users are only created through my application ? Would anyone with my firebase credentials (Which are easily exposed in browser) be able to add users to the database ? I understand that there is no domain based locking on firestore, but is user creation atleast domain based ?
Thanks!
Firebase Authentication is the only way to populate the request.auth variable in security rules. So if you want to secure based on a user, you'll need to create that user in Firebase Authentication.
You can however:
Use anonymous authentication to generate a UID for users, without requiring them to enter credentials.
If you have an existing sign-in system, you can hook that up to Firebase Authentication as a custom provider. This would then make your user details available in request.auth in the security rules.
To lock access to your Firestore database down to users from a specific domain, you'd use something like this in your security rules:
request.auth.token.email_verified &&
request.auth.token.email.matches(".*#google.com")
So this only allows access once a user has verified the email address in their profile, and if that email address is from he given domain.

Login with Email/Password without enabling it

My current registration process looks like this:
App sends a registration request via my REST Api to my backend with information like username, password, email etc.
My backend checks if the username is available. If it is, it creates a new user with the admin api. If this is successful as well it saves the username to the realtime db.
When I want to log in with loginWithEmailAndPassword it says that I can't because PasswordLogin is disabled.
Since I don't want anybody to just register with registerWithEmailAndPassword I want to keep it disabled.
My question now is, how can I log a user in without enabling Email/Password?
Or would there even be a possibility to exploit the system when I enable Email/Password?
EDIT: What I'm not sure about is if registrations with registerWithEmailAndPassword are guaranteed to be from my app?
firebaser here
There is no way to sign the user in to a disabled provider. I'm actually quite surprised that you can register them.
There is no way to prevent users from registering after you enable the provider.
But it's quite easy to only allow users that your administrative back-end created access to certain data. Just make the admin script write the UID of users it creates to a whitelist:
/whitelist
uid1: true
uid2: true
And then in your security rules only allow access on whitelisted users:
".read": "root.child('whitelist').child(auth.uid).exists()"

Firebase Web Authentication - Administrator Approval for New Accounts

I've got the Firebase Web Authentication pretty much setup and working for oAuth as well as local username/pwds (email addresses).
My question is: Does anyone have an idea as to how to introduce an additional step in there such that new accounts must be approved by a site administrator prior to being fully validated? I was thinking of tweaking/utilizing the user.emailVerified property but I'm thinking that won't work for oAuth users.
Is there an easy way to do this - to add an admin approval step? Or, is there a property in the Firebase Authentication subsystem that I could easily toggle?
Creating a user via Firebase Authentication only provides them with a unique user id. This doesn't allow them any access to your apps or "register" them in any way. That's entirely your purview. It's nothing more than a map of unique credentials (e.g. Facebook IDs or email/password hashes) to unique Firebase IDs.
You can "register" users by having any access privileges you want, and any workflow to get the user added into your Database (or any other appropriate mechanism).
Assuming database, you would write the user profile/meta data into a path, such as /users/$uid, and base your security rules on whether /users/<user id> exists.
To enforce admin approval, the simplest answer would be to maintain a separate path, such as /registered/<user id>/true that's only accessible by admins (and of course by security rules).
Now you can write rules like the following:
{
"...some path...": {
".read": "root.child("registered/" + auth.uid).val() === true"
}
}
Essentially enforcing a registration process.

Where does firebase save it's simple login users?

I am currently using firebase to make an ionic app. I am using firebase simple login for social auth (facebook, twitter, email & password). The auth works perfectly, it $broadcasts the authed user. However it doesn't seem to create a user in the actual firebase db. I was wondering how I can get the users that have been authed using my app.
For most of the authentication protocols it supports, Firebase doesn't store user data anywhere. Even for the protocols where it does store data (I only know of email+password doing this), it stores this information in a place that your application can't access (though you can find those users in the dashboard of your Firebase).
To quote the Firebase documentation:
It does not store profile or user state in your Firebase. To persist user data you must save it to your Firebase.
What most applications end up doing, is keeping a list of users inside their Firebase that they manage themselves. So when a user first authenticates with the application, it creates a node under /users/<uid> that contains the information for that user.
See this section of the Firebase documentation that describes storing user data.
Firebase does not store profile or user state in your Firebase instance. To persist user data you must save it to your Firebase.
Firebase provides multiple authentications services
Using existing social login providers such Facebook, Twitter, Google, and GitHub. Using these services provides an option for your users to access your application without creating a new account.
Using built-in support for logging in with email & password. This requires registration and account creation that is handled by Firebase. The user account information is stored outside you application.
Using a custom authentication to implement existing server-side authentication, single sign-on, legacy systems, or third-party OAuth based services (such as Yahoo).
Once authenticated, Firebase return a variable auth to your application that you can use for authorization and access control. 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.
If you want to persist additional user information such as name
and location, then you need to use auth.uid and store it in your
Firebase with additional profile data.
Internally, Firebase generates JSON Web Tokens (JWTs) and creates authenticated sessions by calling Firebase.loginWithCustomToken() with those tokens. Each user is assigned a uid (a unique ID), which is guaranteed to be distinct across all providers, and to never change for a specific authenticated user.
The user data for firebase authentication is stored in firebaseLocalStorageDb in IndexedDB. After login to website, if you delete firebaseLocalStorageDb, the login user data for firebase authentication is all deleted so you need to log in website again.

Resources