Single firebase login for all users - firebase

I'm currently developing a web app using firebase authentication to make sure only authorized users can access the backend (e.g. firestore).
However, I don't really care about differentiating users but just want a single password based login/authentication. Meaning users come to the site, enter the password they know and then they get access to the protected data (e.g. from firestore). No need to create a own account.
However, I don't think firebase auth supports something like that.
What would likely work is just using .htaccess to protect the page and then provide users with anonymous accounts once they can access the app/page.
However, the browser popup caused by this is not nice enough for my purpose, I would prefer a nicely styled password form in the actual browser window.
What I could try is creating one account and sharing the password for that with all users (and set the email in the background). However, I'm not sure whether this works fine (e.g. multiple users being logged in at the same time on the same account).
Am I missing a simple option to implement such a single password based login shared between users?
Or is it e.g. possible to send a password to cloud functions, check it there and return an access token for an anonymous account from there to the user?

You can just create a single Firebase Auth email/password account and share the credentials with everyone. As long as you trust that each user will not share them with anyone else, and you trust that they will not maliciously overwrite each others' data, it should be fine.

Related

How to manage flow of non logged in users and allow a select few to create accounts (password protecting a page)

I have a Flutter app where most of the users should never log in. I also use this same app for a small selection of users that I personally manage and would like to allow them to create a Firebase account, preferably just with by giving them a password to access the account creation page. Ideally I don't want just anyone to be able to create an account, only those who I have personally given access to. Is there a way I could password protect the account creation page so that only those with access to the password could create an account? Perhaps there is another way to do this? Ideally, I'm not looking to get into a situation where anyone can create an account and then downstream I have to authorize that account so that it has the correct access. I really just want only those with the access upstream to be able to create the account. Perhaps this is not logical but this seems to make more sense than letting accounts be created by anyone and then approved by me after the fact. So my question really is, how do I password protect a page in flutter? Or is this just a bad idea and should I work to manage things downstream? Or is there another solution I have yet to consider?
Have you considered using something like a dynamic link that navigates to the specified page in the app when clicked. firebase_dynamic_links might be of help. Only those who have the link will be able to access it and I presume that you could manage the link actions from the Firebase console.
You could also opt for simplicity and create a password field that pops up before your account creation page

Do users need to create an account to read/write to Firebase

I'm making an app that has Firebase as its database. The app shouldn't need the user to create an account to use it, but I want the user to be able to read/write their data onto the database (so maybe they have to create an account?).
Do I have to make the users create an account in order to use Firebase?
My problem is that my security rules are read/write are allowed for everyone (which I know is wrong, but how do I change them and not need users to create an account?) Maybe that's the issue.
It is best to ask them to create an account
Although:
it can be a non-real email address and
there is anonymous auth also available
It sounds like you need the app to remember that user's particular data, so that when they return to the app, it is still their data (and not someone else's) that is being accessed.
To achieve that, we need each person's data to be stored in a different place in Firebase. Traditionally, this is by having them log in to some kind of system, most conveniently Firebase itself, and then the data stored in a branch of the database defined by their user Id.
Without logging in, you could simply ask the user for an identifier, such as "Bob" or "Carol", and then store their data under their identifier. The Firebase database would therefore have the following structure.
users/Bob/highScore: 3000
users/Bob/level: 7
users/Carol/highScore: 5050
users/Carol/level: 9
However this is not secure because there is nothing stopping Carol coming to the app and saying she is "Bob". Any such client-side activity you carry out to attempt to identify the user is not really authentication (in the opinion of Firebase) because all client-side activities can be faked relatively easily.
Firebase Authentication
The standard solution is to use Firebase to authenticate each user (see the Firebase authentication docs for this), and give your app a user Id (such as "8769dsg6f8g7698769876sdgs9") which is unique and known (by Firebase) to be correct.
Firebase security rules
You can then lock down the database using Firebase Security Rules so that only user 8769dsg6f8g7698769876sdgs9 can write to any of the users/8769dsg6f8g7698769876sdgs9/.... part of the database.
If you don't use Firebase to authenticate the user, Firebase will treat the user as unauthenticated and you will have no way to restrict each user to their own section of the database. Either you leave it wide open (to hackers etc!) or users will not be able to access their own personal data on it.
They can use a FAKE email address and password
If your concern is that they won't want to give out their real email address, you can ask them to make up any email address, e.g. mickeyMouse49857430679304#hotmail.com, and set a password. There is no obligation on your app to contact them on that email address or verify that the email address is correct.
Whenever they come back to the app, or access it on another device, they need to remember the fake email address and password.
Of course, if they lose their password, there is no way to reset it.
Anonymous Authentication, but at risk of losing access
The legendary Frank von Puffelen of Firebase, himself, has added a remark about Anonymous Authentication, in the comments below. From what I understand, this avoids them having to make up a fake email address.
I think the weakness of this is that if they lose their local web storage (e.g. if they manually wipe it, or move to another device), there is no way for them to re-access the same account, unless they have planned ahead by adding an email/pw to the anonymous account.
The only real way to have security per-user data storage is to use Firebase Auth to sign in the user, and write security rules to protect the database so that each user can only access their own data. There are no secure alternatives to this for Realtime Database.

Firebase Authentication with popup - allow only registered user

I wanted to create website where I have separate Sign In and Sign Up form. I also want to have Google authentication with Firebase.
I've implemented it like this both on sign in and sign up page:
await FIREBASE_AUTH.signInWithPopup(googleAuthProvider);
But this code will always create new user.
What I would like to do is to block creating new user on sign in page, only log them in if user already exists (e.g. as I require terms of use consent on sign up page, but I don't want to require it on sign up page - it would be quite weird)
There is no way in Firebase Authentication to prevent users from signing up, while still allowing them to sign in if they're already created. The reason for this is that Firebase Authentication merely focuses on allowing users to authenticate themselves, so to prove who they are by providing credentials. What they can then do in your app is known as authorization, and is up to you to implement in your front-end application code, back-end application code, and server-side security rules.
For example, if you use one of Firebase's databases (Cloud Firestore or Realtime Database), you'll typically maintain a list of approved user's in that list (either their email or their UID). Then before granting the user access to specific screens in your app or data in your database, you check if the users exists in that list. If not, you don't grant access to the screen or data.
I don't see an issue here, when a user uses google auth when they already have an account it will create a new account with their in some cases new data he might have changed in his google account.
In case your users hold other data in your database I'm pretty sure there's a google auth API for that issue.

How can I prevent Firebase auth users from changing their email address by themselves?

According to firebase doc, it seems that client side SDK allows email address as well as user profile information to be updated directly.
https://firebase.google.com/docs/auth/android/manage-users#update_a_users_profile
If I build an android app without any UI workflow for users to change email address, I am confident that majority, 99.99%+ of the regular users, will use the app as intended.
However, if certain users investigate/reverse-engineers into the app, learns that it uses the firebase, wouldn't it be possible for them to debug and invoke any one of the Firebase Auth client SDK methods provided? (e.g. Wouldn't it be possible for hacker to change email address [not supposed to be allowed in my app after initial registration] & change photo url to point to something inappropriate images?
With Firestore database, I could use security rules to prevent read/writes, but I wasn't sure how I could do something similar in Firebase authentication.
Yes, it's possible for users to get a hold of the token that would be used to call the backend APIs exposed by Firebase Authentication that would normally be used by the SDK. There is no equivalent to database security rules.
The fact of the matter is that users normally should be able to change their email address, as they might actually need to change email provider at some point. If your app doesn't allow this for some reason, and you have a hard requirement to only use the email address provided by the authentication provider(s) you allow, you should consider writing that value to a database at the time the user account is created. Then, use security rules to prevent the user from changing it there. From that point on, you would only ever trust the value initially written to the database, and never use the email address from the auth provider.
You would probably want to handle writing to the database from a Cloud Functions auth onCreate trigger, so that you control all the logic.
I am now facing the same issue, and I think I will just not worry about the 0.01%. This is mostly because if they change their own email with Firebase Authentication via reverse-engineering and my web server is unaware of their new email, this would not have any impact on the other genuine users except maybe not being able to find them (email is only used in searches for now).

Automatic auth linking

On our app we are using "One account per email address". We want users to sign up using a specific authentication provider, which we keep track of, and stick with it.
What I've noticed today is that if I log in using a Google or Facebook provider I can then send myself a password reset link to the associated email address, which allows me to use the email/password provider instead.
There is a slight difference in behaviour depending on the first provider:
If I use Google first, after I use the password reset link I can now user either provider to log in, and both are linked to the same firebase uid. If I debug, I can see both in the providerDetails array on the authData object I get back from Firebase.
If I use Facebook first, after I use the password link the password provider replaces the Facebook one completely, although it retains the old firebase uid. At this point I can no longer use the Facebook login.
My questions are: is this behaviour intended, and, is there any way to switch it off?
This can cause confusion if say a user logs in using Facebook (which we track) and then later forgets and sends a password reset. It isn't the end of the world because they can carry on using the password login, but it certainly muddies the water.
Thanks
The behavior is intentional.
For end users, if they had signed into the app using Google or Facebook, and later they want to recover the password, the most likely reason is they (or an attacker) can not login with that identity provider.
After the user clicks the password reset link, Firebase removes the non-email identity providers to prevent other people from accessing the account silently. If the user still wants to add Facebook/Twitter login, they can do that via manual account linking (if the app supports).
In case the user's email service is the same as identity provider (e.g. #gmail.com users login into the app using Google), Firebase has an optimization to keep the identity provider since there is no security risk.

Resources