Django Allauth Tutorial | Social logins

Published Sep 08, 2017Last updated Sep 19, 2017
Django Allauth Tutorial | Social logins

A small Django website having following features

  • Login with Facebook
  • Login with Google
  • Custom User model.

Source code can be found on Github [link]

Let’s dive into this project

Custom User model

I used the same custom user model as I used in Twilio Project So, I don’t think we should waste our time in this, let’s dive straight into things which are more important, social logins 🙂

Django-allauth

Django-allauth is awesome django package which supports multiple authentication schemes including OAuth logins. Installation is very easy and can be followed on django-allauth documentation here.

OAuth Protocol Flow

abstractprotocolflow.png

Django-allauth social login: Architecture and Design

allauth-project platform uses custom User model extending AbstractBaseUser, Django-allauth has app named ‘socialaccount’ for managing social logins. The three models of socialaccount of our concern:

  • SocialApp: Most OAuth providers require us to sign up for a so called API client or app, containing client ID and API secret. We need to add a Social App for storing those credentials.

  • SocialAccount: When a User signs up using OAuth social logins, a SocialAccount object is created, containing a foreignkey to User, provider for storing provider’s name, uid for user ID, last_login, data_joined and more important extra_data JSONField for storing all the data returned by OAuth provider after successful user authentication.

  • SocialToken: A SocialToken has foreignkey to SocialApp and SocialAccount, and it stores access_token and its expiry_date.

OAuth Social Login

Edit settings.py to in order to enable social logins like Facebook and Twitter:

AUTHENTICATION_BACKENDS = (
    ...
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',
    ...
)


INSTALLED_APPS = (
    ...
    'django.contrib.auth',
    'django.contrib.sites',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
    'allauth.socialaccount.providers.twitter',
     ...
)

SITE_ID = 1
LOGIN_REDIRECT_URL = "/dashboard/"

#urls.py

urlpatterns = [
    ...
    url(r'^accounts/', include('allauth.urls')),
    ...
]

Here, AUTHENTICATION_BACKENDS adds allauth’s authentication backend. INSTALLED_APPS include apps required for allauth and for social login with Facebook and Twitter. LOGIN_REDIRECT_URL sets url where user is redirected after successful login (including social logins). SOCIALACCOUNT_PROVIDERS sets different parameters for OAuth provider, like FIELDS sets parameters to be stored after they are returned by provider after social login. Scope sets parameters which we need permission for while “Grant permission” process of OAuth login. etc.

Firstly we need to create an app on developer portal of Facebook [link]. Registering the app will give us Client ID and Client Secret. Similarly, for Google+ we need to create an app on developer console of Google [link]. Then we need create a  two new SocialApp each for Facebook and Google with these credentials.

Integrating django-allauth with our custom user model

When ever user uses social login for first time, he/she has to grant permission to allauth-project. After this user logs in, behind the scenes, a User instance is created and then a SocialAccount instance is created, allauth sets username and email of User but not other custom fields which we have made!, like we have full_name field in our custom model (have a look in twilio project, same custom model used here, link) and extra_data field of SocialAccount instance of user is JSONField which contains “full_name” parameter. So we need to fire a post_save signal whenever SocialAccount gets updated or saved. Have a look:


def save_profile(sender, instance, **kwargs):
   print(instance)
   instance.user.full_name = instance.extra_data['name']
   uid = instance.extra_data['id']
   instance.user.profile_picture = instance.get_avatar_url()
   instance.user.save()

post_save.connect(save_profile, sender=SocialAccount)

So, this snippet show how save_profile is called after SocialAccount instance having a Foriegnkey to user instance is saved and user’s full_name is saved. similar approach can be followed for other user fields also.

Discover and read more posts from Rishabh Agrahari
get started
Enjoy this post?

Leave a like and comment for Rishabh

5
2