For users of internet services, there are only a few things worse than having to manually sign in (and sign-up) with different websites. The ordeal of the manual sign-in process can be associated with the difficulty that the user may experience in having to remember multiple strong passwords.

The inability to remember a password could lead to the creation of multiple accounts on the same platform or the outright switch to browsing as an unauthenticated user (where it doesn’t prevent access to the sought-after information or service).

Modern web applications solve this problem using social authentication, which is primarily a way to allow users to sign in (and sign-up) with the application using login information from a social network provider that they already have an account with.

In this tutorial, we will build a simple Django application that allows users to sign in via their Facebook, Instagram and LinkedIn accounts. To achieve this, we will use the social-auth-app-django library. We will also learn how to extract additional information such as profile picture and username from the respective social accounts.

At the end of this tutorial, we will have the final application that works like this:

In this section, we will up a new Django project and install dependencies. Let’s start by creating a new folder and making it the present working directory:

$ mkdir django_social_app
$ cd django_social_app

We will create and activate a new virtual environment using Pipenv; this has the effect of creating an isolated Python environment and preventing us from polluting the global package directory when we install Django dependencies. We will also install django and social-auth-app-django:

$ pipenv shell
$ pipenv install django social-auth-app-django

social-auth-app-django simplifies the implementation of social authentication with Django.

Let’s create (and navigate into) a new Django project, we will call it social_app:

Configuring the authentication classes

Behind the scenes, Django maintains a list of “authentication backends” that it checks during user authentication. If the first authentication method fails, Django tries the second one, and so on, until all backends have been attempted.

The AUTHENTICATION_BACKENDS array contains a list of authentication backend classes (as strings) and is by default set to:

['django.contrib.auth.backends.ModelBackend']

We can update it and add new authentication classes in order to allow authentication with the social platforms we are considering in this tutorial.

To update it this, simply add the following code in the settings.py file:

We just added the authentication backend classes for Linkedin, Instagram and Facebook.

You can find a list of the authentication backends classes supported by social-auth-app-django here.

Adding templates and static files

We’ve only worked on setting up and configuring the application, let’s move on to something visual now. In this section, we will build the foundation of the templates that will display the application.

Let’s create a new folder in the coredirectory, we will call this folder templates:

In the settings.py file, we need to set four new values — LOGIN_URL, LOGOUT_URL, LOGIN_REDIRECT_URL and LOGOUT_REDIRECT_URL — because they will be used in redirecting the user when authentication is complete:

In this section, we will do the heavy lifting and set up authentication via Facebook.

Get Facebook Credentials

Head over to the Facebook Developers’ page, after signing in, click on Add a New App and enter the details for the app on the modal window that appears:

Once the app has been created, you will be redirected to the application’s dashboard. On the left side of the screen, click on** Settings, then click on the **Basic option that appears directly underneath it.

When the new screen loads, under the App Domains section, add localhost like this:

Now scroll down until you see an option that says Add Platform, Click on it and select the Website option. This will create a website section where you will see Site URL, add http://localhost:8000/ in the input and click on the Save Changes button:

Now, copy the App ID and App secret from the applications dashboard and add them to the settings.py file:

We can see that a new User (besides the superuser) has been created in the Users category:

We will also see that there is a new account under the User social auths category:

The explanation for the existence of these new accounts is: When a user logs into the application using Facebook (or any social network provider), a new User and User Social Auth instance are created. The User Social Auth is linked to the User account the first time, then subsequently, the User instance is simply queried from the database.

The User instance is created using the details received from the social network provider. In this case, Facebook sent back the first_name and last_name fields of the created User Instance, and the username is a concatenation of the first_name and last_name.

Some social providers (like Instagram) will return the user’s username on their platform and this is used (instead of the concatenation) for the created User instance on the application.

We don’t want our application to just display a username, we want to get additional *User *data such as profile picture, so let’s request for extra data from Facebook.

Replace the YOUR_APP_* keys with the values from your Facebook application dashboard.

The social_django context processors help in adding backend and associations data to template context. This makes it easy for us to access data about the authenticated user using template tags. You can read more about it here.

When a user logs into the application via Facebook, we can access a subset of the user’s data using permissions; permissions are how we ask if we can access the data on Facebook. In the code above, SOCIAL_AUTH_FACEBOOK_SCOPE contains a list of permissions to access the data properties our application requires. The email and user_link permissions request access to the user’s Facebook email and profile link respectively.

Clicking on Continue as USERNAME will grant the application access to user’s private data on Facebook and for this reason, to request for some permissions, you will need to submit your application to be reviewed by the Facebook team to ensure that the returned data isn’t misused. You can find the list of Facebook permissions here.

SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS has a key — fields — where the value is a list of attributes that should be returned by Facebook when the user has successfully logged in. The values are dependent on SOCIAL_AUTH_FACEBOOK_SCOP .

When a user logs in using Facebook, the Facebook API returns the data requested in SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS. To store the data in the database, we need to specify them in SOCIAL_AUTH_FACEBOOK_EXTRA_DATA.

The extra data will be stored in the extra_datafield of the User Social Auth instance:

Now, let’s update the frontend to display the extra data we received from Facebook, we will open the home.html file and replace its content with this one:

Get API credentials

On the screen that comes up next, click on Register a New Client and fill out the details for the application:

Note: Instagram (and most social network providers) require a redirect URL which will be the address the user’s browser will be directed to after the authentication. For this tutorial, we will use this address http://localhost:8000/social-auth/complete/instagram/. You can learn more about this here.

Successful registration of the application will return a screen like this:

Now, we will click on the Manage option to get the application’s Client ID and Client Secret:

Replace the YOUR_CLIENT_* keys with the values from your Instagram application.

With the code above, once a user is authenticated via Instagram, a user object will be sent back to the application. We add this object to SOCIAL_AUTH_INSTAGRAM_EXTRA_DATA because we want it to be stored in the database for easy reference.

Replace the YOUR_CLIENT_* keys with the values from your LinkedIn application.

The SOCIAL_AUTH_LINKEDIN_OAUTH2_SCOPE array contains the permissions needed to access the user’s data, similar to what we saw when we set up authentication via Facebook.

The SOCIAL_AUTH_LINKEDIN_OAUTH_FIELD_SELECTORS array contains the list of data that should be returned when the user is successfully authenticated via Linkedin. It is similar to the SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS array for Facebook. You can find the full list of data items that can be requested for here.

The SOCIAL_AUTH_LINKEDIN_OAUTH2_EXTRA_DATA array contains the data that we want to store in the database for later reference.

We have come to the end of this tutorial and have learnt how to set up social authentication in Django using the social-auth-app-django library with minimal configuration. We have also learnt how to request extra user data once the user has been authenticated via a social network provider.

As we already discussed at the beginning of this article, the importance of social authentication in modern web applications cannot be overemphasized.

Jobs!

Jordan Irabor is a software engineer with a true passion for Web Development, Technical Writing and Graphic Design. He is currently based in Nigeria and has written a lot of technical articles on several websites and blogs including Scotch and Stackshare. His development stack primarily comprises JavaScript, Python, Golang and PHP.

When he is not writing code, learning a new framework or drafting a technical article, Jordan is playing a lead guitar with his rock band and making new music for the ears that appreciate sonorous sounds.

He also does public speaking at tech meetups, and his theoretical knowledge from acquiring a BSc in Computer Science sometimes helps him in applying best practices while programming.