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
If you navigate to http://127.0.0.1:8000/ you should see the default Django welcome screen.
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.
# 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.
# 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.
# 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 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.
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:
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.
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. Use your newly-created superuser credentials to login.
The admin homepage should look like this now:
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.
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.
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
# 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:
# 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.
<!-- 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 ''
.
# 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/ to logout from the superuser account.
Then navigate to the homepage at http://127.0.0.1:8000/ to see the logged out greeting.
Sign Up with Github
Login with Github by clicking on the "Sign Up" link and you'll be redirected to the 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.
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.