Django-allauth tutorial
Tags: django, python, tutorial, beginners
Published: 2020-02-06 14:50:30

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](https://github.com/pennersr/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 <a href="https://djangoforbeginners.com/initial-setup/" target="\_blank">setup guide</a>.

Here we'll create a new directory called `myproject`, install Django with [Pipenv](https://docs.pipenv.org/), 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
```

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

![Django welcome page](https://dev-to-uploads.s3.amazonaws.com/i/a1sfoc5h62bgsntmkjiy.png)

## 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
```

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.

```python
# 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...
]
```

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.

```python
# config/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.

```python
# 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
]
```

Now `migrate` our changes to update the existing database.

```
(myproject) $ python manage.py migrate
```

## Github OAuth

[OAuth](https://oauth.net/) 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](https://github.com/settings/applications/new).

![Github OAuth page](https://dev-to-uploads.s3.amazonaws.com/i/ufsasfk087tsh8oa682t.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/fg6pjqxnty2a9mxq4msa.png)

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](http://django-allauth.readthedocs.io/en/latest/providers.html) docs.

After hitting the "Register application" button you'll be redirected to the following page.

![Github Tokens page](https://dev-to-uploads.s3.amazonaws.com/i/2rbwaboh5vihxibw6q8e.png)

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 `python manage.py runserver` and then navigate to the admin page [http://127.0.0.1:8000/admin](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](https://dev-to-uploads.s3.amazonaws.com/i/1hxh2sk1keyu7pl5ikgw.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/51tpynxm7tcdeies3p6l.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/zivqz7gszkpefzuq6g21.png)


## 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
```

```python
# config/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:

```python
# config/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.

```html
<!-- 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 %}
```

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 `''`.

```python
# 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
]
```

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/](http://127.0.0.1:8000/admin/) to _logout_ from the superuser account.

![Admin logout](https://dev-to-uploads.s3.amazonaws.com/i/pjjo2v82iulz6euj8s6i.png)

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

![Homepage logged out](https://dev-to-uploads.s3.amazonaws.com/i/2utqb9banuayu38nozsc.png)

## 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](https://dev-to-uploads.s3.amazonaws.com/i/k0mbcs7bb26nmxwcmdy3.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/qeghfuny6xpjwtdcr5nv.png)

## 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](http://django-allauth.readthedocs.io/en/latest/overview.html) from here for more information.