Skip to content

Instantly share code, notes, and snippets.

@mehemmelbachir
Created July 9, 2018 08:41
Show Gist options
  • Save mehemmelbachir/5a643bee11412664aac1d56be8b8218a to your computer and use it in GitHub Desktop.
Save mehemmelbachir/5a643bee11412664aac1d56be8b8218a to your computer and use it in GitHub Desktop.
Firebase authentication class for DJANGO Backend.
from django.contrib.auth import get_user_model
from firebase_admin import credentials, auth
from firebase_admin.auth import UserRecord, AuthError
import firebase_admin
from django.conf import settings
import logging
logger = logging.getLogger(__name__)
User = get_user_model()
cred = credentials.Certificate(settings.FIREBASE_SDK_KEY_PATH)
firebaseapp = firebase_admin.initialize_app(cred)
class FirebaseAuthentication:
def authenticate(self, request, token=None):
try:
decoded_token = auth.verify_id_token(token)
user_uid = decoded_token['uid']
user_record = auth.get_user(user_uid)
provider = user_record.provider_data[0].provider_id
# Except value error, if token in the request is not valid
except ValueError as vErr:
logger.warning('[ValueError] %s'%vErr)
return None
# Except authentication failed due to
except AuthError as aErr:
logger.warning('[AuthError] %s'%aErr)
return None
else:
logger.info('Authenticate from firebase using %s'%provider)
if user_record:
try:
user = User.objects.get(username = user_uid)
except User.DoesNotExist:
user = User(username=user_uid)
user.is_active = not user_record.disabled
user.email = user_record.email
user.first_name = user_record.display_name
user.set_unusable_password()
if provider == 'password':
user.first_name = user.email.split('@')[0]
if provider == 'phone':
user.first_name = user_record.phone_number
user.email = user_record.phone_number
user.save()
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(username=user_id)
except User.DoesNotExist:
return None
@mehemmelbachir
Copy link
Author

How to?

SDK Conf file:

  • Get the SDK Configuration file on json format from the Firebase console and add it into your project's root,

settings.py

In your settings.py file add this configuration

 # Path to your SDK Configuration file
 FIREBASE_SDK_KEY_PATH = 'sdk-conf.json'

 # Set first line to authenticate using firebase UIDToken
 AUTHENTICATION_BACKENDS = [
     # add path to your FirebaseAuthentication' class
     '...FirebaseAuthentication',
     'django.contrib.auth.backends.ModelBackend'
 ]
 ...

Login view

from django.contrib.auth import authenticate
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from rest_framework import status
import logging

logger = logging.getLogger(__name__)


class ObtainAuthTokenFromFirebase(ObtainAuthToken):
    permission_classes = [AllowAny,]

    def post(self, request, *args, **kwargs):
        user = authenticate(request, token=request.body)
        if user is None:
            logger.warning('[WARNING] Authentication failed using firebase token')
            return Response('Invalid firebase auth token', status=status.HTTP_400_BAD_REQUEST)

        token, created = Token.objects.get_or_create(user = user)
        return Response({'token':token.key})


obtain_auth_token = ObtainAuthTokenFromFirebase.as_view()

Now you can authenticate using Firebase UIDToken
The authentication class will generate User instance on your backend based on firebase' user_record objects,
You can customize attribute mapping.
I will sooner publish a ready to use django application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment