No one likes creating and remembering a password for each site they visit so it has become increasingly common to allow login via another site like Gmail, Facebook, or Github. Django itself does not support social authentication but the excellent 3rd party package django-allauth does.

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.

Custom User Model vs django-allauth

A common question at this point is: ok, which user auth approach should I use?

I hate when experienced developers reply with “it depends” so I’ll just tell you my preference, which is to use django-allauth all the time. If I want to add social auth in the future, no problem. If I want to just use email vs username for signups/logins, it has me covered. And since it is a custom user model itself, you can add additional fields as needed.

The potential downside is that we’re relying on a 3rd party piece of software, something not maintained by Django itself. However django-allauth is actively maintained, popular, and recommended by many prominent Django advocates. It is also used in the most popular Django starter-kit out there Cookiecutter Django.

So as 3rd party packages go, it’s as safe as it comes. That said, I wish its functionality was baked into Django itself. Maybe one day.

Setup

We’ll create a new directory for our code, install Django in a virtual environment, and start a new Django project called socialauth. Then we run migrate to configure our database and runserver to confirm everything worked correctly.

As elsewhere in the book the name of the virtual environment is shortened here to (social) for simplicity.

$ cd ~/Desktop
$ mkdir social
$ cd social
$ pipenv install django
$ pipenv shell
(social) $ django-admin startproject socialauth .
(social) $ python manage.py migrate
(social) $ 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. Type Control-c to quit the server and then on the command line type the following:

(social) $ pipenv install django-allauth

We need to update our settings.py file. First we’ll add the following code to the INSTALLED_APPS setting. The ... represents existing code above our new entries. We’re adding the built-in sites app as well as four allauth specific apps here.

# socialauth/settings.py
INSTALLED_APPS = [
  ...
  'django.contrib.sites',
  'allauth',
  'allauth.account',
  'allauth.socialaccount',
  'allauth.socialaccount.providers.github',
]

Order matters in INSTALLED_APPS so your complete config should now look like this:

# socialauth/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',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.github',
]

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 the built-in sites app, and configure a redirect to the homepage upon successful login.

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

SITE_ID = 1

LOGIN_REDIRECT_URL = '/'

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.

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

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

On the command line now type Control + c to quit the local server and migrate our changes to update the existing database.

(social) $ 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:

(social) $ python manage.py createsuperuser

Now we can start the server again with python 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. So far in this book, we’ve created a new app each time we add a page to our project. But in truth we don’t have to create a new app to do this. If you step back and think about what Django truly needs to display a webpage it boils down to a url, a view, and a template. So apps are truly optional. Indeed if you read open-source Django code it’s common to see completely different configurations online.

The first time I realized this, my brain almost exploded.

Mindblown gif

This flexibility is powerful but also confusing when starting out. That’s why I’ve tried to be consistent in how we configure our Django projects and apps in this book. But it’s cool to understand we don’t have to.

Therefore for demonstration purposes we’ll add a homepage without adding an app. Note though that in a real app with multiple static pages you likely would want a dedicated pages app.

First create a new project-level views.py file on the command line:

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


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

Now update settings.py file to tell Django to look in a templates folder.

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

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

(social) $ mkdir templates
(social) $ 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.

# socialauth/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.HomePageView.as_view(), name='home'),
]

Ok, now spin up the local server with python 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.




Sign up for the Django For Beginners newsletter for updates when new chapters are available and special discounts for the print edition of the book.