Django comes with a robust built-in authentication system for users but it does not provide support for third-party (social) authentication via services like Github, Gmail, or Facebook. Fortunately the excellent 3rd party django-allauth package does in just a few steps.

In this tutorial we’ll cover how to add login with Github to a basic Django site. The process is almost identical for other 3rd party services including Facebook, Gmail, Twitter, and many more.

Setup

If you don’t already know how to install Django and work with virtual environments, please refer to this setup guide.

Here we’ll create a new directory, install Django with Pipenv and start a new Django project.

$ cd ~/Desktop
$ mkdir myproject && cd myproject
$ pipenv install django
$ pipenv shell
(myproject) $ django-admin startproject myproject .
(myproject) $ python manage.py migrate
(myproject) $ python manage.py runserver

If you navigate to http://127.0.0.1:8000/ you should see the default Django welcome screen.

Django homepage

django-allauth

Now we can install django-allauth and configure our project. Start by using pipenv to install it. Type Control-c to quit the server and then on the command line type the following:

(myproject) $ pipenv install django-allauth

We need to update our settings.py file. First we’ll add several lines of django-allauth config to the INSTALLED_APPS setting. Order matters so make sure these new settings are below existing apps as follows.

# myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites', # new

    'allauth', # new
    'allauth.account', # new
    'allauth.socialaccount', # new
    'allauth.socialaccount.providers.github', # new

    # custom apps go here...
]

Then at the bottom of settings.py we need to specify that we’re using the allauth backend, add a SITE_ID since allauth uses this, and configure a redirect to the homepage upon successful login.

# myproject/settings.py
AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
)

SITE_ID = 1

LOGIN_REDIRECT_URL = 'home'

The django-allauth package is installed so now we need to add it to our urls. You can use any suffix you want but the official documentation uses accounts/ so we’ll use that too. Make sure to add include to the top line of imports.

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
]

Now migrate our changes to update the existing database.

(myproject) $ python manage.py migrate

Github OAuth

OAuth is an open standard for authentication between systems. When a user logs into our site with their Github account, we will redirect them to Github which then sends us a token that represents the user.

To configure a new OAuth application on Github, go to https://github.com/settings/applications/new.

Github OAuth page

It’s important to fill out the Application Name, Homepage URL, and Authorization callback URL. The Application description is optional. Here are the settings we’ll use:

Github OAuth page filled in

The Application name is what the user will see is requesting permission to access their Github account. The Homepage URL is as described. The Authorization callback URL takes a particular form for each integration as defined in the django-allauth docs.

After hitting the “Register application” button you’ll be redirected to the following page.

Github Tokens page

Pay particular attention to the Client ID and Client Secret. We’ll be using those shortly. Also note that in the real-world, you’d never want to publicly reveal either of these keys!

Django admin

We need to configure the admin portion of our Django project. Create a new superuser so we can login! Follow the prompts after typing the command below:

(myproject) $ python manage.py createsuperuser

Now we can start the server again with ./manage.py runserver and then navigate to the admin page http://127.0.0.1:8000/admin. Use your newly-created superuser credentials to login.

The admin homepage should look like this now:

Admin page

We need to make two updates to the admin for django-allauth to work correctly. First go to the Sites portion and set the domain name to 127.0.0.1. The Display Name is for internal admin use so we can leave it as is for now.

Admin sites page

When you deploy your Django application live you’d replace 127.0.0.1 here and on Github with your actual production homepage. We use the localhost for testing purposes.

Next go back to the admin homepage and click on the add button for Social Applications on the bottom. This is where you configure each third-party OAuth. We’re using Github so that’s the Provider. We add a name and then the Client ID and Secret ID from Github. Final step is to add our site to the Chosen sites on the bottom. Then click save.

Admin social applications page

Homepage

Let’s build a simple homepage with links to login for the first time and if a user is logged in, to greet them by name.

We’ll need to create a view, update our urls, and make a new template.

First create a new views.py file with the following code:

(myproject) $ touch views.py
# myproject/views.py
from django.views.generic import TemplateView


class Home(TemplateView):
    template_name = 'home.html'

We’re using the built-in TemplateView to display a template named home.html. By default Django will look within an app for the templates folder but to keep things simple we can create a project-level templates folder and tell Django to look there, rather than in an app.

In our settings.py file, update the settings for TEMPLATES from 'DIRS': [], to the following:

# myproject/settings.py
TEMPLATES = [
    ...
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ...
]

Then create this new project-level templates folder and an home.html file within it.

(myproject) $ mkdir templates
(myproject) $ touch templates/home.html

Now fill in our home.html file. We’ll load socialaccount from django-allauth at the top and then display a message to the user if logged in. Otherwise we’ll provide a link to login with Github.

<!-- templates/home.html -->
{% load socialaccount %}

<h1>Django Allauth Tutorial</h1>
{% if user.is_authenticated %}
<p>Welcome {{ user.username }} !!!</p>
{% else %}
<a href="{% provider_login_url 'github' %}">Sign Up</a>
{% endif %}

The format of our link is the same for other 3rd party auths. In other words, we’d basically swap out github for facebook to have the same effect. Check the django-allauth docs for any additional configuration you’d need but the overall approach is the same.

Finally update our urls.py to point to the new homepage.

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
    path('', views.Home.as_view(), name='home'),
]

Ok, now spin up the local server with ./manage.py runserver and navigate to the homepage at http://127.0.0.1:8000/admin/ to logout from the superuser account.

Admin logout

Then navigate to the homepage at http://127.0.0.1:8000/ to see the logged out greeting.

Homepage logged out

Sign Up with Github

Login with Github by clicking on the “Sign Up” link and you’ll be redirected to the Github authorize page.

Github authorize page

Click on the “Authorize” button and you’ll be redirected back to our homepage with a greeting for your Github account name.

Homepage loggedin

Conclusion

We’re all done! You can look at all users by navigating back to the admin panel at any time.

django-allauth comes with a robust list of customizations we can add, including a logout link, requiring email confirmation, and much more. I encourage you to refer to the official docs from here for more information.

Want to customize your user model but don’t need social auth? I’ve written a separate tutorial on how to extend a custom Django user model that might be of interest.