Verify firebase token – python

This use case happens when Firebase is implemented at frontend or AppEnd side and you have to verify the firebase token at API-end or backend side. A realtime example of this is when in an app, a user login with an OTP. In this scenario, firebase implementation will be at App-end. When an OTP is verified, a token is returned by firebase to app. Now app will send this token in login API. At APIend, you have to verify the firebase token before proceeding to login/signup. To verify the token, you have to connect to the same firebase project which is implemented at App-end.

Step 1: get service account key

Download your serviceAccountKey.json file from firebase console and place it in the root directory of your project.

Here is how serviceAccountKey.json file looks like.

{

 "type": "service_account",
 "project_id": "XXXXXXXXXXX",
 "private_key_id": "XXXXXXXXXXX",
 "private_key": "-----BEGIN PRIVATE KEY-----\n XXXXXXXXXXX \n-----END PRIVATE KEY-----\n",
 "client_email": "XXXXXXXXXXX",
 "client_id": "XXXXXXXXXXX",
 "auth_uri": "https://accounts.google.com/o/oauth2/auth",
 "token_uri": "https://oauth2.googleapis.com/token",
 "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
 "client_x509_cert_url": "XXXXXXXXXXX"
}

Step 2: Install firebase-admin module

Activate your virtual environment and Install firebase-admin module using pip.

pip install firebase-admin

Step 3: Integrate firebase

Create a file firebaselib.py and paste the code shown below in the file.

import firebase_admin
from firebase_admin import credentials

#used to verify id_token
from firebase_admin import auth

import os
from os.path import join
import json
from django.http import JsonResponse

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

#cred = credentials.Certificate("path/to/serviceAccountKey.json")
cred = credentials.Certificate(BASE_DIR + "serviceAccountKey.json file name")
default_app = firebase_admin.initialize_app(cred)

def verifyToken(idToken = None):   
   if idToken:
       try:          
           decoded_token = auth.verify_id_token(idToken)
           return {"status": True, "token_data": decoded_token}
       except Exception as e:
           return {"status": False, "message": str(e) }

In firebaselib.py file , replace serviceAccountKey.json file path with path where your serviceAccountKey.json  file resides.

 

verify_id_token() will verify the firebase token and return success/error response. We can take action based on the response.

We are done with firebase integration. Now we have to use firebaselib.py to verify the token. If you are using django, you can use this in views.py file.

# import firebase lib
from firebaselib import verifyToken

Call verifyToken function to verify the token.

decoded_token = verifyToken(firebaseToken)

Here is the sample of success response when firebase token is valid and verified.

{
"iss": "https://securetoken.google.com/xxxxxxxxx",
"aud": "xxxxxxx",
"auth_time": 1564484497,
"user_id": "CtlbmGGw3DSf6oVO6lXoKoryspA1",
"sub": "CtlbmGGw3DSf6oVO6lXoKoryspA1",
"iat": 1564484500,
"exp": 1564488100,
"phone_number": "+919999999999",
"firebase": {
             "identities": {
                  "phone": [
                       "+919999999999"
                   ]
              },
              "sign_in_provider": "phone"
          },
"uid": "CtlbmGGw3DSf6oVO6lXoKoryspA1"
}

We can get the user details from the response and use these details while verifying the user. For example, we can add a condition where we match the phone number associated with firebase token and the phone number received in the login request.

if decoded_token['status'] == False:
    #error
else:
     if 'token_data' in decoded_token and (
                       decoded_token['token_data']['phone_number'] == requestData.get('phone_number', None)):
          # phone number matched
          # Create a new user or login existing user
else:
          # Unauthorized access

If you are implementing this code in Django rest framework, your login function will look like this. Modify code shown below according to your requirement.

"""
Header:
Token: <FIREBASE_TOKEN>

POST Request params
{"phone_number": "+919999999999"}
"""

class Login(APIView):
   """
   User Login
   """

   def post(self, request, *args, **kwargs):
       # fetch POST data
       requestData = request.data
       requestHeader = request.headers

       if 'Token' in requestHeader:
           responseData = {}
           responseData['data'] = []

           # print("token received")
           decoded_token = verifyToken(requestHeader['Token'])
           if decoded_token['status'] == False:
               # Error in login, check firebase token error in decoded_token['message']
               # print(decoded_token['message'])
           else:
               if 'token_data' in decoded_token and (
                       decoded_token['token_data']['phone_number'] == requestData.get('phone_number', None)):
                   # print("phone number matched")
                   # create new user if not exist
                   # or login if user already exist
               else:
                   # Unauthorized access
       else:
           #Token can not be empty.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top
Shares