Django Social Apps Authentication
Tags: python, django, webdev, codenewbie
Published: 2021-08-31 08:49:42

When websites ask us to login into their website to use their services, how many of us get tired of filling out credentials? Well, I know I do :) Nowadays most web apps have integrated social authentication into their system without asking for excess credentials from the user. And of course social authentication has a lot of crucial advantages from the developer side as well.

Social login uses information from social networking sites like Google or Facebook to help ease and facilitate the registration/login process on third-party applications.

------------------------------------------------------------------

We are going to implement a Google, and Github authentication using the [**social-auth-app-django**](https://python-social-auth.readthedocs.io/en/latest/configuration/django.html) library.

- First thing is first let's install this library to make use of the service it provides.

```python
pip install social-auth-app-django
```

Install the app in the *settings.py* module.

settings.py
```python
INSTALLED_APPS = [
    # ...
    'social_django',
]
```

Apply migrations so that django will create the necessary models related to the `social_django` app.

`python manage.py makemigrations`
`python manage.py migrate`

Okay, all good. Now we have to add authentication backends to the settings, but before that **what does it mean to add authentication backends?**

- Well, up until now we have been using the default authentication system that comes with django. But more often than not, we may need to use other authentication sources when attempting to authenticate a user.

Django keeps track of a list of authentication backends when authenticating a user. It then uses these backends **in order** to authenticate a user. This list is defined in *settings.py* under the [AUTHENTICATION_BACKENDS](https://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#authentication-backends).

Alright, let's define the correct backends we need for our app. As I mentioned in the beginning, I'm going to use Google and Github authentication backends so let me go ahead and add those.

```python
AUTHENTICATION_BACKENDS = (
    'social_core.backends.github.GithubOAuth2',
    'social_core.backends.google.GoogleOAuth2',

    'django.contrib.auth.backends.ModelBackend',
)
```
- `django.contrib.auth.backends.ModelBackend` is the basic authentication backend which comes by default in django to let users login by username/password method. The ones above it are Google and Github backends to use within our app for social authentication.

Now inside *settings.py* go to `TEMPLATES` list and add the following to `context_processors`.

settings.py
```python
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                
                # Add the following two
                'social_django.context_processors.backends',
                'social_django.context_processors.login_redirect',
            ],
        },
    },
]
```
- Whenever a template is rendered with a request, a context is also returned. Imagine we are building an app where we have to include the same data in every view we create. It is hard and prone to error right. This is where context processors come in to play. `context_processors` contains a list of paths to callables which will return a dictionary to be merged with context of each view saving us the trouble of having to add the same data over and over again.

- Okay, let's move on to the next part which is updating the project's *urls.py* module to include the social auth app's urls.

user_management/urls.py
```python
# add the following imports
from django.urls import path, include
from django.conf.urls import url

urlpatterns = [
    # add this new url entry to include the social auth's urls
    url(r'^oauth/', include('social_django.urls', namespace='social')),

]

```

**_Edit:-_** _`django.conf.urls.url()` is removed in Django 4.0+, so instead use `re_path` as follows:_

```python
# add the following import
from django.urls import re_path

urlpatterns = [
    # add this new url entry to include the social auth's urls
    re_path(r'^oauth/', include('social_django.urls', namespace='social')),

]
```

Okay, to get this up and running the next step is to register our app in Google and Github.

------------------------------------------------------------------

### Github Authentication 

Step 1 - Login to your Github account
Step 2 - Go to Settings -> Developer Settings -> OAuth Apps -> New OAuth App

Step 3 - Fill in the information

![Github OAuth App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eph5cgoa0bno6ot91muo.png)

- Except for the Authorization callback URL, you can fill out the rest of the information as you like. 
- **Authorization callback URL** is the most important part of setting up your OAuth application. After a user is successfully authenticated, Github returns him/her to this callback URL.
- [*Read more... Authorizing OAuth Apps*](https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#web-application-flow)

After filling out the information, you will be provided with unique Client ID and Client Secret. In the next part we will see how to keep these keys safe using python-dotenv, but for now since the main topic of this part is social authentication let's focus on that.

settings.py
```python
# social auth configs for github
SOCIAL_AUTH_GITHUB_KEY = 'YOUR GITHUB KEY'
SOCIAL_AUTH_GITHUB_SECRET = 'YOUR GITHUB SECRET KEY'
```

**TEMPLATES**

Now let's update the login template to use the Github backend. Remember in the last part of the series we had *sign in with Github* and *sign in with Google* as dead links, so open *login.html* and go to the anchor tag `href` attribute that has a dead link to *sign in with Github* and update it as follows.

login.html
```html
<a href="{% url 'social:begin' 'github' %}" class="btn btn-link btn-lg active btn-block">Sign in with GitHub</a>
```

That's it, you can now login to the site using your Github account.

------------------------------------------------------------------ 

### Google Authentication

Step 1 - Go to [Google Developers Console](https://console.cloud.google.com/projectselector/apis/dashboard?supportedpurview=project&project=&folder=&organizationId=&rif_reserved)
Step 2 - Go to the credentials section in the left menu and create a new project
Step 3 - In the create credentials menu, select OAuth client ID
Step 4 - Select web application as the type of application and fill in the required information.

- Authorized redirect URIs is where users will be redirected to after they are authenticated.

- [*Read more... Using OAuth 2.0 for Web Server Applications*](https://developers.google.com/identity/protocols/oauth2/web-server)

![Authorized redirect URIs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4pbv0fapli3zhythbpq.png)

- Now you will be provided with a Client ID and Client Secret which we will be using in the *settings.py*.

settings.py
```python
# social auth configs for google
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'YOUR GOOGLE KEY'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'YOUR GOOGLE SECRET KEY'
```

Go to *login.html* and update the following
```html
<a href="{% url 'social:begin' 'google-oauth2' %}" class="btn btn-link btn-lg active btn-block">Sign in with Google</a>
```

Well done! once you get around setting up your first social authentication, the process is somewhat similar for other social networks like Twitter or Facebook as well. The difference is how each social network lets us register our app in their system.

### Is it working as it should? 
- Start the development server and run the usual command `python manage.py runserver` in your terminal.
- Go to localhost and try to login with Github or Google.

Thanks for your time. You can find the finished app in [github](https://github.com/earthcomfy/Django-registration-and-login-system). See you next time with another part of the series.

Any comments and suggestions are welcome.