Firebase subaccounts - firebase

I'm currently building a POS/Store admin app, when a user gets into my app, the Owner of the store will then be asked to login only once for setup purpose (e.g. a new machine), the app will then display a list of staffsName that has already been added by this owner, and then everytime a staff wants to start a new transaction, he/she will only need to click on his/her name, then enter his/her 4-digit pincode to 'login' and process the transaction.
How do i go about achieving this?
I was thinking of using firebase auth for the 'login' of the staff, but then when i log in using the staff credential, I will lose access to the uid of the owner, which is needed to access the owner's store data such as his/her products.
i'm also thinking of using firestore to store the 4digit pincode, but then i'm also concerned about security

There are multiple ways you can approach this, one where you utilize the email login by simply appending a fake domain to the username to create a valid email domain. This user account could be the designated 'user' in question, or utilize credentials inside custom claims or hidden in a database that allows the client or server (depending on your preference) to then log in as the user.
Moreover if you want the manager to login once you can add Authentication State Persistence to specify whether a signed in user should be indefinitely persisted until explicit sing out, page reload etc.
Another approach requires the user also to have a valid auth that is not an email password and you link your pin auth to that main account with Firebase Auth Linking per the documentation: https://firebase.google.com/docs/auth/web/account-linking.
This does however require that the user be registered from an auth provider such as Google, Twitter, Apple, etc. then the user will have to activate this link by logging in for authentication purposes. This can in theory be automatically generated and processed without the user knowing.
It is a long way around it since this is essentially a custom solution but it does create the flow you are looking for without having to use a custom auth provider.

Related

Have one user signup another user with custom fields in firebase/flutter

I am trying to determine if the following scenario is possible with flutter and firebase:
we have users within the company who will be given access to the app, where on the homepage will be a signup another user button where they enter in that user's email and password, they get signed up, and then the original user specifies custom fields for the 2nd user, such as company name, role, position, etc.
Is this possible with flutter and firebase?
Have asked the flutter google group and was told about custom authentications, but from what I see that is just an external authentication system and doesn't show me how to let one user create another users profile with fields.
Any ideas?
The first thing to consider is whether those properties need to be in the user profile at all. The user profile is sent with every request, and should only contain information that is relevant for securing access. If you have additional information to store about the user, you should store it elsewhere (such as in one of Firebase's databases) using the UID of each user as its key.
Assuming that the information is about security (such as the role seems to be, there is no secure way to let one user set security properties (typically referred to as claims) from client-side code. As soon as this is allowed from client-side code, anyone could set such properties for anyone else. That's why setting custom claims for a user is only possible with Firebase's Admin SDKs, which are designed to run in a trusted environment - such as your development machine, a server you control, or Cloud Functions.
There are a few other options, but it's important to realize they're all implemented on top of the above approach.
There is an experimental extension that allows you to set auth claims by writing a document into Firestore, which something like this (JavaScript syntax, but the Flutter code will be similar):
db.collection("user_claims")
.doc("abc123")
.set({
role: "admin",
groups: ["example1", "example2"],
});
Now of course you'll want to make sure that you secure writing to the user_claims collection, as otherwise you'll end up with the same security risk I mentioned in the first paragraph, where everyone can claim any role they want.
Alternatively you can write your own server-side API (for example on Cloud Functions) that you expose to your application, and that then calls the Admin SDK. Here too, it is important to secure access to this API, to ensure only authorized users can call it.

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.

Firebase: Implementing Switch / Add Account Features

I am working on Firebase application ( Firebase version 4.1.3 )
My health care related application is made for dependent group of people such as children and seniors. However, most of my users are independent group of people age around 18-55. Most of my users use my application for their seniors/children. They need to create account for each of their family seniors/children member. Therefore, my users have to log in and out many times and they have to keep track of their family members' account. My first thought was I should make an account switching feature so that my user can switch their account back and forth between their family members to update information on my application.
After searches on Google, I found way to force switching account on Firebase authentication with Google provider, but those are not what I'm looking for.
My questions are:
Is it possible to store the multiple firebase auth objects (logged in object) in client side?
If it is possible, for how long will the token inside the firebase auth object last for?
If it doesn't last forever, is it possible to refresh update the token so that it can be use without authenticating with the social/phone login again?
The functionality you are asking for is not available out of the box. You have to build it on your own. I do think Firebase provides the pieces to allow you to build it (via Auth and Database).
Is it possible to store the multiple firebase auth objects (logged in object) in client side: You can have multiple Firebase app instances and each one have an auth instance with a current user. You would need to ask each user to authenticate though (you can't authenticate once and sign-in into all of the account). However, you can build your own user group login mechanism, where logging in with one "master" account can allow you to login with multiple accounts using custom Auth.
If it is possible, for how long will the token inside the firebase auth object last for. Firebase sessions are supposed to be indefinite. If a token expires (typically after one hour), it can be refreshed automatically if you are using real time database.
I do not think Firebase has that token capability. But what you could do is simply put the email address of the people in the device by Shared Preferences( for Android). When the user wants to log in with that user bring the email address just ask him to enter the password and then go through the log in process. If you do not want to use SharedPreferences you could simply store the users(also as you said family members) in Firebase Database and link them with the controller user so to speak. Whenever user wants the switch, go and bring the email addres of other family members from Firebase Database and ask in the client for the password and do the login by Firebase Authentication.Hope that helps!

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.

How to set the Principal in an ASP.Net app

I am writing a web app for a client. Users will have a one-time key that they will use to initially identify themselves to the app. Once the app verifies that the key is valid it will take them to a page where they can create a normal account to use for all subsequent logins. The create-account page should only be accessible after entering the key and shouldn't be accessible otherwise. I.e, it shouldn't be accessible to users logged in with a normal account.
This is asp.net 3.0 using a custom membership provider.
My plan is to create a temporary account based on the key and authenticate the user with that account. This allows them access to the create-user page (which is protected with a location tag ) where they can create the formal account. I then authenticate them with their new account and delete the temporary account.
The flow is: the user goes to a page where they enter the key. If the key is valid I create the temporary account, call FormsAuthentication.SetAuthCookie, and redirect to the create-account page. This all works, although it seems a little complicated.
The problem is that the create-user page is available to any authenticated user; I only want it available during the time between entering the key and creating the formal account. So I thought I'd create a special role for the temporary account and make the create-user page accessible only to that role and none other. I created my own Principal object with a special role and tried setting it when I authenticate the temporary account but I can't get that to work.
I'm really hoping I don't have to write a custom role provider just to do this.
How can I make this work? There's gotta be a simpler way!
Why not simply create the real account when they enter the key. Assign it some random name and then let them change the name and other details. Then you don't need the create user page, just the enter key page and an account details editing page. If you're concerned about getting the account details filled in, you could set it up (perhaps via code on a MasterPage) so that incomplete accounts always get redirected to the edit details page until the details are entered.
Or, you could have them enter the required details in addition to the key code on the enter key page and simply use those details when creating the account.
My advice would be to avoid the use of temporary accounts when validating the user. Instead, generate your own logic for validating the sign-up key. Then, at the head of the page, you can check whether the user is an authenticated user (SetAuthCookie has been called) and jump to a different page if this is true.
You may even be able to change the page access to forbid this page to authenticated users (I know you can disable accounts for unauthenticated users but I'm not sure if you can go the other direction).
The key, though, is to avoid relying on the membership provider when, in fact, the user is not yet a member!
Assign an "incomplete" role when authenticating against the temporary token, then restrict access to only that role... when the account is created, send them to a re-login page (terminating the authentication token). This will simplify your security model.

Resources