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.
Related
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.
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.
I am developing an app for my college and there are different types of users called students ,teachers , hod's
etc. When they login, how do I know a teacher logged in, or a student logged in? Is there any function in firestore for role based signups and signins?
I was thinking that when a teacher signs up, I will add a tag end of her uid.username that if username is 'DANIEL' while signup, I will add a tea for teachers and stu for students at the end of the name what they provided.
So when they login i will get the uid and do the string manupulations and get the last three letters so that i can know who logged in so that i can show different UI to Different types of users
Is there any best way to do like this ?
while singning up user enters his username example:"daniel"
i will update that username in uid.username like this "daniel-stu"(if student signed up),"daniel-tea" if techer signsup.
Storing this information in the user's display name can work. You can read it back from there next time, and take action in your application's client-side code. But note that this means that any user can change their role, since they can also call the same code to update their profile. If that is not a concern for your app, then this approach sounds like it would work.
If malicious users should not be able to change their role, then you shouldn't set that role from the client-side application code. In that case, you can set the role from a server (or your development machine, or Cloud Functions) using the Admin SDK. Since the Admin SDK runs in a trusted environment, it has expanded privileges and can update the profile of any user. So the Admin SDK could update the display name of the user in the same way you have in mind.
But this still isn't secure, since you're still setting a property that anyone can modify for their own profile. Again... if that is no problem for your app that is fine, but if the use-case requires that you can rely on the property to be correct, we have to keep looking elsewhere.
The Admin SDK can set additional so-called claims on a user profile that client-side code can't modify. Such claims are for things that affect the permissions of the user, such if the user is an admin, or what role/group your users belong to. This sounds quite close to what you are describing, so can also be used. And this time, only your code that runs in a trusted environment will be able to do so.
Finally, you could store the additional information about a user in the database. It's quite common to have a collection (Users or Profiles) in the database, where you store a document for each user (with the document name being User.uid). You create the document when the user first signs in, and update whenever you need to. You can do this from the client-side code (if there is no need to control what gets written), or from code that runs in a trusted environment (such as your development machine, a server you control, or Cloud Functions) if you do need to keep control. A big advantage of this approach is that all users can potentially see the information in this collection, where the client-side Authentication SDK only allows a user to read their own user profile.
For more on this, see:
Adding new data to firebase users (in which I essentially list the same options with fewer words)
Add extra User Information with firebase (store the information in the realtime database)
Associate Firebase Users to Database Records (also using the realtime database for the additional information)
Cloud Firestore saving additional user data
this video explaining custom claims
and many more previous questions on this topic
CONTEXT:
In firebase settings, there's a permissions tab. This shows the users/emails that are associated with accounts that have admin access to the firebase project and console.
I could have sworn I once saw a document describing a method or some way of checking if a user account in firebase auth is also an administrator of the firebase project.
I seriously can't tell if it was in a dream (yes I dream code) or if I actually saw it. I often work late nights and fall asleep in front of my computer.
Question: Is there any way to tell if a user is also an administrator of the firebase app?
IE the user email matches an email that’s listed in the IAM/access management section of firebase as an 'owner' role?
Im currently writing an admin panel for my app, so such a feature would be very useful.
If such a thing does not exist, can anyone suggest an alternative way to manage and authorise users that are capable of logging into the admin dashboard to have control over the app? I already understand custom claims so I will use them if no better solution is suggested.
Well, using only the FirebaseAuth through your app, I don't think you can (as far as my knowledge goes). But you can easily implement the Admin SDK to manage your Custom Claims. Basically, you can use the Admin SDK and find out which "role" you want to access.
Referencing Firebase
Custom claims can contain sensitive data, therefore they should only
be set from a privileged server environment by the Firebase Admin SDK.
and
Custom claims can only be retrieved through the user's ID token.
Access to these claims may be necessary to modify the client UI based
on the user's role or access level. However, backend access should
always be enforced through the ID token after validating it and
parsing its claims. Custom claims should not be sent directly to the
backend, as they can't be trusted outside of the token.
Once the latest claims have propagated to a user's ID token, you can
get them by retrieving the ID token.
Therefore, you'll only need the FirebaseAuth implemented on your app's (client), but will need an extra implementation using a server.
Please see the Firebase use cases, they'll probably fit your needs, and you can pick the one that is "easier" for you.
It turns out it can't do what I wanted in the first place because it's only available on certain triggers.
Here it is: context.authType
https://firebase.google.com/docs/reference/functions/functions.EventContext#.authType
The level of permissions for a user. Valid values are:
ADMIN Developer user or user authenticated via a service account. USER
Known user. UNAUTHENTICATED Unauthenticated action null For event
types that do not provide user information (all except Realtime
Database).
Although it would be great if we could get this information on callable functions and firebase triggers because it would help further secure hosted backend admin apps for customer service or developers, who have high-level access to admin functions. This variable seems to not be available on callable functions but is available on newUser trigger - which is strange, because how can user signup ever be authenticated anyway?
If I create a new product, use simple auth, there is a "create user" API. How do I restrict it so that only invited emails (either by the email or via a one-time key) can sign up? Doesn't seem to fit easily into the rules, but I am probably missing something.
First, I should point out that the core Firebase API uses JSON Web Tokens for auth, which you can generate yourself, so you have full control over the creation of user accounts and can restrict it however you like:
https://www.firebase.com/docs/security/custom-login.html
I'm guessing you're referring to our Simple Login service.
Simple Login is a service that provides some common login options. It has no way to restrict creation of new accounts. However, you can restrict what those accounts can do with Firebase. For example, you could set your security rules up so that only user accounts in some authorized list (in Firebase) are actually able to read or write data.