Authentication

Add Authentication to your Django Application

One can build a web application with the Python programming language, and there are several options for choosing a web framework. Two good frameworks are Django and Flask. In the previous post "Securing Your Flask Application Using Kratos and Keto", we discussed how to build a Flask application with authentication. Let's do the same thing for Django.

Django is a web framework for perfectionists with deadlines and can help build web applications quickly. It has its authentication and permissions framework, admin interface, and a lot of integrations with popular relational database systems such as PostgreSQL, Percona Server, SQLite, MySQL, and MariaDB.

I love building web apps using Django because it was my first web framework, and I love its ecosystem. In this tutorial, we'll build a simple one-page application with authentication powered by the Ory Network.

Let's start hacking, huh?

Bootstrap Django project

Django has many ways to bootstrap a project:

  1. Django Cookiecutter is a framework for jumpstarting production-ready Django apps. It's a useful framework generating everything you need for the Django project, including docker support, integration with Cloud storage such as S3, and more.
  2. django-admin command. We'll use it because we want to build something simple, and it would be easier for local development.

To run this tutorial it is also recommended to install Poetry to manage python dependencies.

mkdir django-ory-cloud
cd django-ory-cloud
poetry init

This command will guide you through creating your pyproject.toml config.

Package name [django-ory-cloud]:
Version [0.1.0]:
Description []:  An example django application with the Ory Network as an Authentication backend
Author [John Doe, n to skip]: John Doe
License []:
Compatible Python versions [^3.10]:

Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file

[tool.poetry]
name = "django-ory-cloud"
version = "0.1.0"
description = "An example django application with the Ory Network as an Authentication backend"
authors = ["John Doe"]

[tool.poetry.dependencies]
python = "^3.10"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"


Do you confirm generation? (yes/no) [yes] yes

Installing Django

poetry add Django
Creating virtualenv django-ory-cloud-0UeuvAWs-py3.10 in /Users/gen1us2k/Library/Caches/pypoetry/virtualenvs
Using version ^4.0.4 for Django

Updating dependencies
Resolving dependencies... (1.0s)

Writing lock file

Package operations: 3 installs, 0 updates, 0 removals

  • Installing asgiref (3.5.1)
  • Installing sqlparse (0.4.2)
  • Installing django (4.0.4)

Creating project

poetry run django-admin startproject mysite

It generates the following project structure and you can learn more about the structure here

.
├── mysite
│   ├── manage.py
│   └── mysite
│       ├── __init__.py
│       ├── asgi.py
│       ├── settings.py
│       ├── urls.py
│       └── wsgi.py
├── poetry.lock
└── pyproject.toml

2 directories, 8 files

Now it's time to install additional dependencies such as django-environ to enable configuration via environment variables and django-ory-auth to enable integration with the Ory Network

poetry add django-environ django-ory-auth
Using version ^0.8.1 for django-environ
Using version ^0.1.3 for django-ory-auth

Updating dependencies
Resolving dependencies... (2.4s)

Writing lock file

Package operations: 7 installs, 0 updates, 0 removals

  • Installing certifi (2021.10.8)
  • Installing charset-normalizer (2.0.12)
  • Installing idna (3.3)
  • Installing urllib3 (1.26.9)
  • Installing requests (2.27.1)
  • Installing django-environ (0.8.1)
  • Installing django-ory-auth (0.1.3)

poetry shell
cd mysite

Enabling django-ory-auth package

On the previous step we installed django-ory-auth package. We need to add it to the INSTALLED_APPS by editing mysite/settings.py file.

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
+    'django_ory_auth',
]

Let's discuss the next steps of our integration. Django-ory-auth package comes with a context processor and an authentication backend. The context processor provides additional context such as login_url, logout_url, and many more to use in templates. The authentication backend replaces the default Django authentication backends because we store identity data in the remote identity provider.

It works fine with AUTH_USER_MODEL and Django's permission framework. You can still use is_staff and is_superuser fields of the default user model.

Add this to the mysite/settings.py file:

AUTHENTICATION_BACKENDS = [
    "django_ory_auth.backend.OryBackend",
]

Django's default settings do not have an out-of-the-box configuration for templates, so we need to make additional changes. This example uses mysite/templates folder to store templates, and we need to make further changes.

Edit mysite/settings.py:

# Add import os to the beginning of the file
import os
import environ

env = environ.Env()
...
# We need to change a couple of settings here
TEMPLATES
...
        # This tells django to use `mysite/templates` dir
        # for searching templates
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # Add this line to enable context processor
                # and have variables like `login_url` available
                # in templates
                'django_ory_auth.context.processor',
            ],
        },
...

Set up the Ory Network

Okay, for the next steps we need to have an Ory Network project and install the Ory CLI.

  1. Create Ory Network project
  2. Install Ory CLI
tip

You can create a new Ory Network project with the Ory CLI: ory create project --name example

To connect your Ory Network project, you need to copy the Ory SDK URL. You can find it by opening Connect from the sidebar of the Ory Console. The URL follows this pattern https://projectid.projects.oryapis.com. We can use the playground project for demo purposes.

Add it to the mysite/settings.py

...
ORY_SDK_URL=env("ORY_SDK_URL", default='https://playground.projects.oryapis.com')
ORY_UI_URL=env("ORY_SDK_URL", default='https://playground.projects.oryapis.com/ui')

We have now added authentication to the Django backend!

Build a simple webpage

Adding a new webpage in the Django framework is straightforward. One needs to create

  1. A template
  2. A view
  3. Add a view to the URL patterns

Let's start with the template. Create templates/base.html with the following content:

The example uses TemplateView in this example because of its simplicity. Edit mysite/urls.py and add the following lines:

Run it and test it

At this point, we have everything set up for the Django project.

Start Django:

export ORY_SDK_URL=http://127.0.0.1:4000/.ory
export ORY_UI_URL=http://127.0.0.1:4000/.ory/ui
poetry run ./manage.py runserver

Start Ory Proxy:

export ORY_SDK_URL=https://playground.projects.oryapis.com
ory proxy http://127.0.0.1:8000

Open http://127.0.0.1:4000 and click Login to get started

Use it with Ory Kratos self-hosted

You can use django-ory-auth with Ory Kratos self-hosted. You can run everything using the following docker-compose.yml

Run Django

export ORY_SDK_URL=http://127.0.0.1:4433
export ORY_UI_URL=http://127.0.0.1:4455
./manage.py runserver

Open http://127.0.0.1:8000 and click Login or Signup to get started.

Next steps

  1. Add Two Factor Authentication (2FA) to your App
  2. Add social signin features
  3. Configure more secure password policies
  4. Implement email and phone verification and account Activation
  5. Deploy Django App to production
Never miss an article - Subscribe to our newsletter!