Firebase is giving only a set of limited methods for authenticate users like email/password, mobile number, google, facebook, etc. It has almost everything that most people need. But sometimes we need to use a custom authentication server which is in the premises, an LDAP server or some other OAuth2 provider. That’s when custom token authentication method in the Firebase Authentication Server is useful.
But why use Firebase Authentication without using the authentication system that we are currently having (as mentioned above)? Some reasons that come into my mind are listed below.
Before going into the code, I will describe how custom token authentication is done in few steps.
I will use a cloud function as the backend server. If you are new to cloud functions, you can find some articles here in this blog. Also you can read the documentations given by the google. Take a look at the cloud function documentation from Firebase. I find it really easy compared to the GCP cloud function documentation.
I’m using a cloud function with HTTPS endpoint for this demonstration. But with few modifications, this can also be used for callable cloud functions. You can see a simple cloud function below that will return "Hello World" as the response after calling the API. I used typescript for coding.
You can use the following cURL command to test the cloud function. Make sure to update the cloud function endpoint with the one you got after deploying.
Before generating a custom token, we need a separate authentication server. To mock a separate authentication server, I will just create an async function as follows. I will call it the mock auth system. This system will return true if the given user is authenticated and false if not.
The only user in the mock auth system has the id ‘ABC-1234’ and passcode ‘123456’. We need to modify the endpoint to
Therefore, the definition of the endpoint has to be changed as follows.
A custom token can be generated with Auth.createCustomToken(id) method. It will require an ID that can be used to uniquely identify the user inside Firebase. We know the id given as the credential is unique in the mock auth system. To make it unique inside Firebase, we will simply use the suffix "MOCK". Then the unique id that will be used to create custom token will be MOCK-ABC-1234.
The following typescript code will return a custom token as I discussed earlier. It will not do any validation or edge case testing. Just an implementation of what I explained.
As we are using Firebase Admin SDK, we have to add these lines before calling the admin SDK for the first time.
After deploying the new function with npm run deploy, you can run the previous cURL command. You see the ‘invalid id or passcode’ msg as expected. You can use the following cURL command to create a custom token.
When you run the above command, you will get the following error message instead of the custom token.
IAM Service Account Credentials API has not been used in project 217740369248 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/iamcredentials.googleapis.com/overview?project=217740369248 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.;
Please refer to https://firebase.google.com/docs/auth/admin/create-custom-tokens for more details on how to use and troubleshoot this feature.
This happens because you need to enable IAM Service Account Credential API for this project. That service is used to sign a JSON Web Token (JWT), which is a JSON text with some information that can be used to uniquely identify the user. JWTs created by Firebase are using OpenID Connect JWT specs and therefore they have these information in it. Custom token which is created by Firebase Admin SDK is really a signed JWT. Therefore the project should have the above mentioned service enabled.
There are 3 ways that can be used to enable that service. All of them are described in this documentation. I will use the 2nd method here, which is letting Admin SDK to automatically detect the service account. It is the most secure and least painful way. (Actually all these methods are very secure in the Google’s end. I said the other 2 are less secure because they involve some security measures that need to be taken place by the programmer also. You know, programmers!!).
To enable the service you need to,
Click the link given by the error message, which is https://console.developers.google.com/apis/api/iamcredentials.googleapis.com/overview?project=217740369248. You can also go to this page by visiting APIs & Services -> Library in GCP console. Then search for IAM Service Account Credential API.
Then click Enable API button. It will take some time to enable it.
Then visit Access -> IAM page in the GCP console.
Then locate the service email address which is in the format <project_id>@appspot.gserviceaccount.com. Click the edit icon at the right side of the table, next to that email.
Then click “+ ADD ANOTHER ROLE” button in the appeared pane. Select the role as “Service Account Token Creator”. If everything is as follows, click save.
You will have to wait about 5 minutes to populate everything. Then use the last cURL command to get the custom token. You will see the following.
Now you can use this Custom Token to log into firebase authentication server. In the following section, I will put some code for authentication in different clients.
To access Firebase REST API, you need an API key. You can get the API key to your project from the Firebase Console. Goto Project Settings section, General Tab. Under “Your Project” you will see a value with the key “Web API Key”. Copy that value and that is you API key.
You can run the following cURL command to login. Replace [API_KEY] with the copied “Web API Key” and [CUSTOM_TOKEN] with the token you received from the previous step using the endpoint just created.
You will get a json output and you can use those values in other endpoints in Firebase REST API.
First you need to setup your web application to support Firebase. You can see the official documentation here. The use the following code to login in with the CUSTOM_TOKEN.
First you need to setup your mobile/web application to support Firebase. You can see the official documentation here. Then use the following code to login in with the CUSTOM_TOKEN.
For other clients also, first you need to setup your project with Firebase. Then you have to use appropriate API.
First you need to understand why you need custom token authentication for your app. It is because you need to authenticate your app with a 3rd party authentication server (maybe some OAuth2 server), but at the same time you need all the cool features Firebase Authentication brings to your app. I think I cover all the things that you need to know when generating a Custom Token and when you are using it in the client side of the application. And as always, write a comment if you have anything to ask. I create a gist with this code and you can access it via following link.