I recently started working with firebase functions. My intention is to have a function that "all users" within my app can use. More specifically I want everyone that is signed in to their account to be able to call this function. You can't reach calling the function without being logged in.
Would it be appropriate to use the authentication "allUsers" to this function in google cloud, or does this tag mean more than what I specified?
The Cloud Functions setting "allUsers" allows all users, not just those of your app. If you want to restrict usage to just the users of your app, have a look at Firebase App Check which you can use to enforce this requirement.
As #ESun commented too, if your users are signing in with Firebase Authentication, you can validate that too. See How to protect firebase Cloud Function HTTP endpoint to allow only Firebase authenticated users?
Related
Edited
I am building a spa app to make some administrative tasks on the app/firebase easier. I don't have a separate backend for this app so I use firebase cloud functions directly from the spa client. I am also not using Admin Sdk , just Http triggers. I am using functions.https.onCall on functions invoked by regular app users. Since i didn't want to mix up regular users with the admin login , I implemented a separate login for the spa app. Since the admin is already logged in , I am looking for some kind of JWT key / API key based authentication to secure firebase functions implemented for these tasks.
One possible solution , as Frank van Puffelen mentioned in his answer , is to add firebase auth , store the UIDs of the admin users and check if the request came from them using getIdToken() in the cloud function. Is this the best practice or is there an alternate to approach this.
Any input is appreciated.
The common approaches here are to:
Either keep a list of the UIDs of the admin users in a place that your Cloud Function can access, for example in the code itself or (more likely) in a cloud-hosted database.
Or add a custom claim to the ID token of admin users.
In either case, your Cloud Functions code can then ensure the user is authorized to call the end point.
This question already has an answer here:
Firebase functions: Securing firebase https functions
(1 answer)
Closed 2 years ago.
I am building a Flutter Android app where an user can sign in with a customToken. I have a (Google) Cloud Function that I use to generate a customToken which is sent back to the client (Android App) to sign into Firebase. (the auth provider is not supported by Firebase as of yet - not to my knowledge anyway)
For security and cost-savings purposes, I want to only allow the Cloud Function to be accessed by authorised users, and hence, I removed the allUsers member as a Function Invoker role.
I then created a service account (within the same Firebase project) and gave it the Function Invoker role. The problem now is how do I "authenticate" the client (Android App) to access this function, without being signed in (since you need the customToken to sign in), and also without saving credentials on the client?
Or am I approaching this problem the wrong way? Should that Cloud Function be public? My knowledge of Firebase, Cloud Function and security is also very limited, so any advice/suggestion would be greatly appreciated.
Cloud IAM user permissions (such as allUsers and service accounts) don't have anything to do with Firebase Auth users.
Cloud Functions that need to be directly accessible by web and mobile clients must have IAM allUsers permission. They don't need a service account for permission.
If you need to check the Firebase Auth user account that's invoking the function, the client will need to pass an ID token to the function, and the function will need to verify that token with the Firebase Admin SDK in order to find out who the user is, then decide if the should be able to continue execution. This process is described in more detail in the documentation.
If you aren't using Firebase auth, there's not much else you can do from a security perspective, as you would have to include the credentials in the app itself, or otherwise make those credentials publicly available, which is not secure at all. Or in other words, you can't limit access to your function from just your own app code.
I'm writing an app with Flutter and Firebase (using both Firestore, Storage and Authentication so far).
Currently the app shows content from Firebase, but now I'm trying to figure out how the best way is to implement writing/editing/removing stuff in Firebase.
The goal is to have users with admin privileges.
My question is if I can build an Admin Panel inside the client app (which would be ideal), or if that's considered bad practice and I should build an Admin Panel in another app and using Cloud Functions.
For example, currently I perform Authentication (signup/register) in the Flutter/Dart code and when registering it creates a field in Firestore isAdmin = false, which I then can manually set to true (if I want) in the Firestore console. Could this somehow be an "unsafe" way of doing this?
The goal is to have users with admin privileges
Since you are using the Authentication service you already have half of the solution: with authentication you can identify each user who is using your app.
The other part is Authorization: this is normally done with Security Rules in Firebase, both for Firestore and Cloud Storage.
To be able to authorize certain users (identified through authentication) with Admin privileges, you need to know which users have the admin role in such a way you authorized them to execute the admin functions.
One possible way to identify the admin users is to have an isAdmin flag in some user documents in Firestore, as you mention in your question. There is an example of Firestore Security Rule using this approach in the documentation.
HOWEVER, you will encounter some problem if you want to use this flag (stored in Firestore) with Security Rules for Cloud Storage. At the time of writing, it is not possible to read the value of a Firestore document in Security Rules for Cloud Storage.
The solution is to use Custom Claims. You will find all the details in the doc on how to implement it in such a way it fulfill your needs.
Can I build an Admin Panel inside the client app?
Yes, you can very well do that. As soon as your security is correctly implemented (through Authentication and Security Rules, as explained above), there is nothing that prevents you to develop an Admin panel. If a user that is not admin can access the Admin panel, he/she will not be able to perform the admin actions (i.e. writing/editing/removing Firestore or Cloud Storage data).
Moreover, with Custom Claims, you can access them in the front-end to modify the client UI based on the user's role or access level (i.e. showing the pages, buttons and menu items of the Admin module only to admin users -note however that this does not prevent someone to reverse engineer your app and execute the queries dedicated to admin users: this is why it is key to correctly implement the Authentication and Security Rules parts-). See this section in the Custom Claims doc.
Should I build an Admin Panel in another app and using Cloud
Functions?
If you don't want to over-complexify your app with some logic to hide/show the Admin panel elements (based on Custom Claims, see above) you can very well build the Admin Panel in another app.
If you have specific needs/access restrictions that cannot be implemented through standard Security Rules you could very well use some Cloud Functions to check the user is an admin and to execute the writing/editing/removing admin actions (note however that while it is quite easy to interact with Firestore from a Cloud Function, it can be a bit more tricky with Storage: using the Cloud Storage Client SDKs is much easier than interacting with Cloud Storage through Cloud Functions).
You would preferably use Callable Cloud Functions, since "with callables, Firebase Authentication and FCM tokens, when available, are automatically included in requests". (See https://firebase.google.com/docs/functions/callable).
Side Note: You may be interested by this article, which details how to to create an Admin module for managing users access and roles. (Disclaimer: I'm the author).
the idea of creating an admin panel for any flutter app
The idea is for two applications with different names and they will be linked to each other with Firebase
for more details see the video from the link
https://youtu.be/d7qoff-I8BU
So I'm trying to build an http endpoint using a Cloud function. This cloud function is only invoked after the user signs in. So I can pass the user token and verify it on the server side. I understand how to do this.
I also have security rules on my Firestore collections with authorization rules set up using request.auth.uid. This also just works if I use the firebase web sdk.
But my question is - how do I use the same authorization rules via cloud functions? I don't want to rewrite my auth logic separately for the http endpoint.
Security rules only apply to access from web and mobile SDKs. It does not apply to code using any of the server SDKs, including the Firebase Admin SDK and anything you would use with Cloud Functions. You will have to apply your own logic to check the validity of data before it's added to Firestore. The same is true for Realtime Database and Cloud Storage security rules.
As you use the admin sdk in your functions, the check for the auth looks a bit different. Just watch this video from The Net Ninja. He is explaining how to do this. Just use the generated token instead what’s been used in the video.
I want to develop an Ionic app for android and ios using firebase backend.
Requirement:
1. I want to use anonymous authentication silently so that user does not have to be worry about login.
2. I just want to display list of some items on the home page using Firestore api.
Question/Problem:
1. How does firebase will get to know that only the my app using the firestore get api.
2. If I am storing api credentials/secrets in my android app and if other user somehow knows these credentials, will that person be able to use api on behalf of my credentials and I will not be able to track the usage.
Top Level:
If someone know my firebase api credentials/secrets, will that person be able to utilize my firebase quota in case I am using firebase anonymous authentication.
Thanks in advance.
The settings you use to initialize the Firebase SDK are not "secrets". It's all very much public information that identifies your app from all the other Firebase apps out there. Every Firebase app has a similar set of public data. Once you publish your app, you should assume that everyone is able to see that data.
This means that anyone can use that data. That's why it's important to use Firebase Authentication along with security rules to make sure that people logged in can only make use of whatever resources you specify. That's the only way to lock down the data in your Firebase project. If you are concerned about security, then you should be thinking about your security rules from the very beginning.