Signup Or Sign-In Using Facebook To Django Application

Signup Or Sign-In Using Facebook To Django Application

Nowadays most of the users are having the facebook account. Registration/Login will take the time fill the form and submit to create or login to our website. Adding the functionality to login/signup with facebook makes it very easy to login or to register to our website.

There are many*third party django packages* are available to add facebook signup or facebook login to our django application. But, third-party packages will also provides the additional functionality that is not required for us. In this article we going to add the login with facebook or register with facebook functionality without using the third-party django packages.

Login to Facebook developers account "https://developers.facebook.com/" . After login goto Facebook Apps page by visiting the link "https://developers.facebook.com/apps/" there you can find the button/link with name "Add a new app", click on it. It will ask for App name or Display name and contact email. After filling the details click on the button "create app id" . On succesfull creation it will redirect us to products page. In products page we can find different products like Analytics, Messanger, Webhooks, Facebook Login, etc. We are implementing the facebook login so, choose the facebook login by clicking on button "setup". It will ask for the type of our application (iOS, Android, WWW, etc). We are implementing it on django web application so choose the web(WWW). After choosing the web we have follow the below steps.

1.Tell Us about Your Website
2.Set Up the Facebook SDK for Javascript
3. Check Login Status
4. Add the Facebook Login Button
5. Next Steps

After finishing the above steps click on the button/link settings which can be find in left side menu. It will show the app details like App ID, App Secret, App Domain, etc. Update the details and copy the App ID, App Secret update these in "settings.py" file.

FB_APP_ID = 'xxxxxxxxxxxxxxxxxxxx'
FB_APP_SECRET = 'xxxxxxxxxxxxxxxxxxxxxx'

Lets talk about the authentication process with facebook login

Our App <===> Facebook App <===> Facebook Servers

Lets start with very basic flow, when user clicks on the login with facebook button/link we redirect the user to facebook login page, after successful completion of the login facebook will returns to our application. Now we will implement it in our django application with the below code.

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^facebook-login/$', views.facebook_login, name="facebook_login"),
]

views.py

from datetime import datetime
from urllib import urlencode
from django.conf import settings
from django.contrib import messages
from app.models import User

def facebook_login(request):
    redirect_uri = "%s://%s%s" % (
        request.scheme, request.get_host(), reverse('app:facebook_login')
    )
    if('code' in request.GET):
        code = request.GET.get('code')
        url = 'https://graph.facebook.com/v2.10/oauth/access_token'
        params = {
            'client_id': settings.FB_APP_ID,
            'client_secret': settings.FB_APP_SECRET,
            'code': code,
            'redirect_uri': redirect_uri,
        }
        response = requests.get(url, params=params)
        params = response.json()
        params.update({
            'fields': 'id,last_name,first_name,picture,birthday,email,gender'
        })
        url = 'https://graph.facebook.com/me'
        user_data = requests.get(url, params=params).json()
        email = user_data.get('email')
        if email:
            user, _ = User.objects.get_or_create(email=email, username=email)
            gender = user_data.get('gender', '').lower()
            dob = user_data.get('birthday')
            if gender == 'male':
                gender = 'M'
            elif gender == 'female':
                gender = 'F'
            else:
                gender = 'O'
            data = {
                'first_name': user_data.get('first_name'),
                'last_name': user_data.get('last_name'),
                'fb_avatar': user_data.get('picture', {}).get('data', {}).get('url'),
                'gender': gender,
                'dob': datetime.strptime(dob, "%m/%d/%Y") if dob else None,
                'is_active': True
            }
            user.__dict__.update(data)
            user.save()
            user.backend = settings.AUTHENTICATION_BACKENDS[0]
            login(request, user)
        else:
            messages.error(
                request,
                'Unable to login with Facebook Please try again'
            )
        return redirect('/')
    else:
        url = "https://graph.facebook.com/oauth/authorize"
        params = {
            'client_id': settings.FB_APP_ID,
            'redirect_uri': redirect_uri,
            'scope': 'email,public_profile,user_birthday'
        }
        url += '?' + urlencode(params)
        return redirect(url)

when user clicks on the login with facebook button we redirect request to facebook with facebook app id, redirect uri for response, scope is to authorize to get the resource. After successful login facebook will return response to our redirect uri with access token code or authorization code. By using the authorization code we send the request to facebook to get the resources from the facebook. In above code I have requested the resources "id,last_name,first_name,picture,birthday,email,gender".
After getting the resource if user is not existed in our database then we create and get a new user otherwise we simply get the user from db. Now, we have user object so, we make the user login and redirect user to home page(in my case).

References:
https://developers.facebook.com/docs/graph-api/
https://developers.google.com/identity/protocols/OAuth2