Firebase Auth with admin sdk? - firebase

I am using firebase firestore as datastore for my web based application. The application has 2 different actors.
Supervisor: logs in via a common password set for all supervisors plus the ability to generate unique codes.
User: logs in via the unique code generated by the supervisor.
I am using cloud functions to do the heavy lifting for both actors. Now these functions are protected with cors and whitelist for origins.
I am trying to secure the routes created with cloud functions with a Auth Middleware relying on the concept of if the request is not from authenticated account or not.
I have created a email and password accounts for both actors for the frontend section of my application.
The question is if I am to go with firebase Auth api to get the refresh token and use it as jwt in the Middleware, will it be an issue since let's say 100 supervisor are connected and performing some tasks, and the same thing for the second actor ? Because after examining the refresh token it contains the uid of the account authenticated and using the same account for multiple connection is the blocking stone in this scenario.

the point of a token to be used in every operation is to validate the origin of the request
Firebase Authentication uses ID tokens to verify the user's identity, not the origin of requests. A malicious user in your scenario can get the credentials from the app, and use them in their own code - calling APIs on your Firebase project.
If you want to only allow calls from your own app, consider using the new App Check feature of Firebase.

Related

Using firebase to authenticate users server-to-server

We use firebase to authenticate a frontend application in the standard process- The application connect to firebase and ask for token, than the application send this token in every API call to the server, and the server validates the token.
Now if we want to expose some of our endpoints and supply api access (e.g users will be able to login without browser), how should we do the authentication?
The users will send username and password, and we will need to authenticate against firebase with the credentials.
Is there best practice or guideline to how to approach this?
I want to still leverage firebase security features that I don't need to manage by myself (for example, preventing brute-force attacks), but not using the browser.

Which is safer - using Firebase auth.createUserWithEmailAndPassword() or using a cloud function?

I'm building a social media app with a focus on group chatting. I am working on creating a new user. Firestore provides this function to begin the process of creating the user from the client:
auth.createUserWithEmailAndPassword
However, I read that it's safer to try to minimize what lives on the client side and do most of the app's work on the server side. Should I use the function above (on the client) or should I make a custom function that passes the email and password to the server and create the user there?
Firstly, auth.createUserWithEmailAndPassword is not a Firestore method. It's a Firebase Auth method. Firestore is a database, Firebase Auth is an authentication service. It's good not to mix up their responsibilities.
The options you're proposing are not, in practice, any different in terms of security. That's because the Firebase Auth service provides a public REST API for creating new user accounts that's accessible to the world if you've enabled email and password authentication for your project. It doesn't really matter if you invoke that from a frontend or backend - the net result is the same.
Do whatever you find most convenient. Firebase Auth was designed so that users can create their own accounts using the authentication providers that you enabled. Adding another backend service to that seems to just add more work for no extra benefit.

What is the purpose of using two tokens in firebase ? - firebase authentication query for a server client web application

Firebase provides a client sdk for web and an admin sdk for backend server to create a user session. In a microservices architecture based cloud application, do we have to create a custom token at the server side when a user tries to log into our system and then allow the client using java-script based client sdk to create another id-token with the custom token for continuing the client interaction within that session ?
Why do we need two tokens i.e Custom Token(Admin SDK) and Id Token(Client SDK) for user authentication ?
You need only one of the two tokens for each user, depending on whether you're using a custom provider to sign that user in, or one of the built-in providers.
If you use one of the existing providers you'll use its ID token.
If you create a custom provider, you'll create your own (custom) token for the user. This custom token essentially takes the place of the ID token that you'd use with the default provider.
To learn all about the various token types that Firebase Authentication has, read the blog post Demystifying Firebase Auth Tokens.

How to authenticate a Firebase user to an IFTTT service?

I'm trying to build an IFTTT service and connect it to my Firebase backend.
I need to authenticate user as indicated in the IFTTT docs:
https://platform.ifttt.com/docs/api_reference#service-authentication
IFTTT’s protocol supports OAuth2 authentication, including support for
refresh tokens if so desired.
Your service API should use access tokens for authentication and as a
source of identity. A single access token should correspond to a
single user account or resource owner on your service.
If refresh tokens are used, they must be non-expiring. If refresh
tokens are not used, access tokens must be non-expiring.
But I can only get short-lived access tokens from Firebase it seems. Where can I get or how can I generate such tokens from the Firebase auth SDK?
Update in response to #FrankvanPuffelen:
I'll create an IFTTT service running on a Node server (possibly simply Cloud Functions) that will use the Firebase RTDB to send formatted HTTP request back to IFTTT. IFTTT requires me to authorize user accounts. Their required UX is something like this:
If an IFTTT user tries to use my service on the IFTTT website,
an auth dialog for my service pops up.
The user logs in and confirms IFTTT's access to their data on my service.
Some OAuth 2.0 tokens are exchanged.
IFTTT servers will periodically send requests (authentified with those tokens) on behalf of the user to my server.
Part of the question is: Can I use the Firebase Auth API to get those tokens, etc. or do I need to create a new OAuth 2.0 "layer" with my own generated tokens for IFTTT?
PS: I'm very new to OAuth, so it's all a bit confusing to me, sorry if the question isn't very clear.
So IFTTT calls Cloud Functions, which then calls Realtime Database, and you want to authentication the IFTT user with Realtime Database. Is that correct? If so, you can either use an OAuth2 token or create a Firebase Authentication session cookie.
Use an OAuth2 token
I did this not too long ago for accessing the Realtime Database from Google Apps Script. The requirements are relatively simple (once you know them):
The OAuth2 tokens must be requested with the correct scopes: https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/firebase.database.
The OAuth2 access token must be present in the request to Realtime Database.
The authenticated user must be at least an editor on the Firebase project. Note that this is not a Firebase Authentication user, but a Google user account.
Also see:
How to integrate Firebase into Google Apps Script without using (deprecated) database secret
Use a Firebase Authentication session cookie
You can also use a Firebase Authentication session cookie, which can be longer-lived (up to 2 weeks) than a regular Firebase Authentication ID token (up to an hour). You'll want to set up a Cloud Function for creating the session cookie, call that from IFTTT, and then pass the session cookie with the IFTTT request and along to the Realtime Database.
For more on this, see:
the Firebase documentation on managing session cookies.
I'm posting my solution here, this is a rough draft of what I did at at the time.
I'm using this auth method: My API has users with non-expiring OAuth2 access tokens and have an Express server responding at a Firebase HTTPS Cloud Function endpoint. Currently, at the prototyping stage, it generates fake tokens from the UID that are successfully accepted by IFTTT.
It's a redirect-heavy authentification flow based on this old IFTTT api example: https://github.com/IFTTT/connect_with_ifttt_auth_sample
Here's the gist of it:
Tokens and Auth Codes are just randomized and encrypted UIDs for now.
/oauth/authorize redirects to my app.
The app asks the user if they want to authorize IFTTT
The app redirects to /oauth/authorize_user
/oauth/authorize_user generates a user-specific code and redirects the user to IFTTT with this code
IFTTT asks /oauth/token to exchange the code for a Bearer tokens.
IFTTT can now make requests on behalf of this user with this bearer token.
Sample code here: https://gist.github.com/nathanvogel/15ed311258b91d7ec3d25f44047780e2

Firebase CREDENTIAL for rest API

Firebase Rest API mentions that we can pass CREDENTIAL to provide access to authenticated nodes. However I was not able to find documentation on where I can find these credential or generate these credential. Custom tokens generated using NodeJS firebase-admin client also don't work.
https://firebase.google.com/docs/database/rest/save-data
https://docs-examples.firebaseio.com/rest/saving-data/auth-example.json?auth=CREDENTIAL
If you scrolled down a little on the same page, you would find the answer:
In the following example we send a POST request with an auth parameter, where CREDENTIAL is either our Firebase app secret or an authentication token...
Firebase secrets are legacy credentials you can find/create under Project settings - Service Accounts in the Console. Using one as the auth parameter gives the caller administrative access.
Or you can use a service account to generate admin level access tokens instead of relying on the legacy secrets. See here for the Java implementation.
Or if you have an authenticated user – for example you're implementing an API a client apps call via HTTP, passing along their current access token –, you can use that token directly to impersonate the user.
The custom authentication tokens serve a completely different purpose and are part of a different sign in flow. Therefore they do nothing via the REST API.

Resources