Django

Gravatar for evan.sims@auth0.com
By Evan Sims

This tutorial demonstrates how to add user login to a Python web application built with the Django framework and Authlib OAuth library. We recommend that you log in to follow this quickstart with examples configured for your account.

I want to explore a sample app

2 minutes

Get a sample configured with your account settings or check it out on Github.

View on Github
System requirements: Python 3 | Authlib 1.0 | Django 4.0

Configure Auth0

Get Your Application Keys

When you signed up for Auth0, a new application was created for you, or you could have created a new one. You will need some details about that application to communicate with Auth0. You can get these details from the Application Settings section in the Auth0 dashboard.

App Dashboard

You need the following information:

  • Domain
  • Client ID
  • Client Secret

Configure Callback URLs

A callback URL is a URL in your application where Auth0 redirects the user after they have authenticated. The callback URL for your app must be added to the Allowed Callback URLs field in your Application Settings. If this field is not set, users will be unable to log in to the application and will get an error.

Configure Logout URLs

A logout URL is a URL in your application that Auth0 can return to after the user has been logged out of the authorization server. This is specified in the returnTo query parameter. The logout URL for your app must be added to the Allowed Logout URLs field in your Application Settings. If this field is not set, users will be unable to log out from the application and will get an error.

Create application

For this guide we demonstrate how to integrate Auth0 with a Python application using the Django framework and Authlib. Let's start by ensuring Django is installed on your system. From your shell, run the following command:

pip install django~=4.0

Was this helpful?

/

If you already have a Python application setup, you can skip to the next step. Otherwise, let's create our new application project. From your shell, run the following command, and switch to the new project folder:

django-admin startproject webappexample
cd webappexample

Was this helpful?

/

Install dependencies

For this integration you'll need few library dependencies, such as Authlib. Go ahead and create a requirements.txt file in your project directory, and include the following:

# 📁 requirements.txt -----

authlib ~= 1.0
django ~= 4.0
python-dotenv ~= 0.19
requests ~= 2.27

Was this helpful?

/

You should now run pip install -r requirements.txt from your shell to make these dependencies available to your project.

Configure your .env file

Next, create an .env file in your project directory. This file will hold your client keys and other configuration details.

# 📁 .env -----

AUTH0_CLIENT_ID={yourClientId}
AUTH0_CLIENT_SECRET={yourClientSecret}
AUTH0_DOMAIN={yourDomain}

Was this helpful?

/

Update settings.py

You'll want to make some minor changes to your webappexample/settings.py file to read those .env values. At the top of the file, add these imports:

# 📁 webappexample/settings.py -----

import os
from dotenv import load_dotenv, find_dotenv

Was this helpful?

/

Next, beneath the 'BASE_DIR' definition, add the following:

# 📁 webappexample/settings.py -----

# Add the following line after 'BASE_DIR = ...'
TEMPLATE_DIR = os.path.join(BASE_DIR, "webappexample", "templates")

Was this helpful?

/

Next, find the TEMPLATES variable and update the DIRS value to add our TEMPLATE_DIR string. This tells Django where to look for our template files, once we create them. Keep any other content of this array the same.

# 📁 webappexample/settings.py -----

TEMPLATES = [
    {
        # Leave other lines as they are; we're just updating `DIRS`.
        "DIRS": [TEMPLATE_DIR],
    },
]

Was this helpful?

/

Finally, at the end of this file, add the following:

# 📁 webappexample/settings.py -----

# Load environment definition file
ENV_FILE = find_dotenv()
if ENV_FILE:
    load_dotenv(ENV_FILE)


# Load Auth0 application settings into memory
AUTH0_DOMAIN = os.environ.get("AUTH0_DOMAIN")
AUTH0_CLIENT_ID = os.environ.get("AUTH0_CLIENT_ID")
AUTH0_CLIENT_SECRET = os.environ.get("AUTH0_CLIENT_SECRET")

Was this helpful?

/

Setup your application

Now you're ready to start writing your application. Open the webappexample/views.py file in your project director.

Begin by importing all the libraries your application will be making use of:

# 📁 webappexample/views.py -----

import json
from authlib.integrations.django_client import OAuth
from django.conf import settings
from django.shortcuts import redirect, render
from django.urls import reverse
from urllib.parse import quote_plus, urlencode

Was this helpful?

/

Now you can configure Authlib to handle your application's authentication with Auth0:

# 👆 We're continuing from the steps above. Append this to your webappexample/views.py file.

oauth = OAuth()

oauth.register(
    "auth0",
    client_id=settings.AUTH0_CLIENT_ID,
    client_secret=settings.AUTH0_CLIENT_SECRET,
    client_kwargs={
        "scope": "openid profile email",
    },
    server_metadata_url=f"https://{settings.AUTH0_DOMAIN}/.well-known/openid-configuration",
)

Was this helpful?

/

You can learn more about the configuration options available for Authlib's OAuth register() method from their documentation.

Setup your route handlers

For this demonstration, we'll be adding 4 routes for your application: your login, callback, logout and index routes.

Triggering authentication with /login

When visitors to your app visit the /login route, they'll be redirected to Auth0 to begin the authentication flow.

# 👆 We're continuing from the steps above. Append this to your webappexample/views.py file.

def login(request):
    return oauth.auth0.authorize_redirect(
        request, request.build_absolute_uri(reverse("callback"))
    )

Was this helpful?

/

Finalizing authentication with /callback

After your users finish logging in with Auth0, they'll be returned to your application at the /callback route. This route is responsible for actually saving the session for the user, so when they visit again later, they won't have to sign back in all over again.

# 👆 We're continuing from the steps above. Append this to your webappexample/views.py file.

def callback(request):
    token = oauth.auth0.authorize_access_token(request)
    request.session["user"] = token
    return redirect(request.build_absolute_uri(reverse("index")))

Was this helpful?

/

Clearing a session with /logout

As you might expect, this route handles signing a user out from your application. It will clear the user's session in your app, and briefly redirect to Auth0's logout endpoint to ensure their session is completely clear, before they are returned to your home route (covered next.)

# 👆 We're continuing from the steps above. Append this to your webappexample/views.py file.

def logout(request):
    request.session.clear()

    return redirect(
        f"https://{settings.AUTH0_DOMAIN}/v2/logout?"
        + urlencode(
            {
                "returnTo": request.build_absolute_uri(reverse("index")),
                "client_id": settings.AUTH0_CLIENT_ID,
            },
            quote_via=quote_plus,
        ),
    )

Was this helpful?

/

There's no place like /home

Last but not least, your home route will serve as a place to either render an authenticated user's details, or offer to allow visitors to sign in.

# 👆 We're continuing from the steps above. Append this to your webappexample/views.py file.

def index(request):
    return render(
        request,
        "index.html",
        context={
            "session": request.session.get("user"),
            "pretty": json.dumps(request.session.get("user"), indent=4),
        },
    )

Was this helpful?

/

Register your routes

Finally, you'll need to tell Django how to connect these new routes. Replace the contents of your webappexample/urls.py file with the following:

# 📁 webappexample/urls.py -----

from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("login", views.login, name="login"),
    path("logout", views.logout, name="logout"),
    path("callback", views.callback, name="callback"),
]

Was this helpful?

/

Add templates

Now we just need to create the simple template files used in the routes about (during render() calls).

Create a new sub-directory within the webappexample folder named templates, and create a index.html file:

# 📁 webappexample/templates/index.html -----

<html>
  <head>
    <meta charset="utf-8" />
    <title>Auth0 Example</title>
  </head>
  <body>
    {% if session %}
    <h1>Welcome {{session.userinfo.name}}!</h1>
    <p><a href="{% url 'logout' %}">Logout</a></p>
    <div><pre>{{pretty}}</pre></div>
    {% else %}
    <h1>Welcome Guest</h1>
    <p><a href="{% url 'login' %}">Login</a></p>
    {% endif %}
  </body>
</html>

Was this helpful?

/

Run your application

You're ready to run your application! From your project directory, open a shell and use:

python3 manage.py migrate
python3 manage.py runserver 3000

Was this helpful?

/

Your application should now be ready to open from your browser at http://localhost:3000.