Django-allauth tutorial

Will Vincent - Feb 6 '20 - - Dev Community

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 called myproject, install Django with Pipenv, and start a new Django project that uses config for the top-level directory name. After migrating the initial database, execute the runserver command to start up the local Django web server.

$ cd ~/Desktop
$ mkdir myproject && cd myproject
$ pipenv install django==3.0.3
$ pipenv shell
(myproject) $ django-admin startproject config .
(myproject) $ python manage.py migrate
(myproject) $ python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

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

Django welcome page

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==0.41.0
Enter fullscreen mode Exit fullscreen mode

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

# config/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...
]
Enter fullscreen mode Exit fullscreen mode

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.

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

SITE_ID = 1

LOGIN_REDIRECT_URL = 'home'
Enter fullscreen mode Exit fullscreen mode

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.

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')), # new
]
Enter fullscreen mode Exit fullscreen mode

Now migrate our changes to update the existing database.

(myproject) $ python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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--and easy to forget!--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
Enter fullscreen mode Exit fullscreen mode
# config/views.py
from django.views.generic import TemplateView


class Home(TemplateView):
    template_name = 'home.html'
Enter fullscreen mode Exit fullscreen mode

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:

# config/settings.py
TEMPLATES = [
    ...
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ...
]
Enter fullscreen mode Exit fullscreen mode

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

(myproject) $ mkdir templates
(myproject) $ touch templates/home.html
Enter fullscreen mode Exit fullscreen mode

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 %}{% endraw %}
<a href="{% provider_login_url 'github' %}">Sign Up</a>
{% endif %}
Enter fullscreen mode Exit fullscreen mode

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 by importing the Home view and creating a new path at ''.

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

from .views import Home # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
    path('', Home.as_view(), name='home'), # new
]
Enter fullscreen mode Exit fullscreen mode

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 logged in

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.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .