Django Passkeys TutorialPasskeys Implementation

Django Passkeys: How to Implement Passkeys with Python Django

This tutorial shows how to add passkeys to a Python Django web app. We use Corbado's passkey-first UI component and implement simple session management.

Blog-Post-Author

Nicolai

Created: November 30, 2023

Updated: August 29, 2024


We aim to make the Internet a safer place using passkeys. That's why we want to support developers with tutorials on how to implement passkeys.

Overview#

1. Introduction

2. Django Passkey Project Prerequisites

3. Repository Structure for Django Passkey Project

4. Set Up Your Corbado Account and Project

5. Django Passkey Project Setup

    5.1. Initialize Project

    5.2. Configure Environment Variables

    5.3. Create Templates With Session Management

    5.4. Create Django Controller and Configure Routes

6. Run Django Application

7. Conclusion

1. Introduction

In this tutorial, well be walking through the process of building a sample application with passkey authentication using the Django web framework made for Python. To make passkeys work, we use Corbado's passkey-first UI component that automatically connects to a passkeys backend.

If you want to run the project straight away, please follow the README of our sample app Github repository.

The result looks as follows:

django passkeys ui component

2. Django Passkey Project Prerequisites

This tutorial assumes basic familiarity with Django and Python as well as HTML and JavaScript. Let's dive in!

Slack Icon

Become part of our Passkeys Community for updates and support.

Join

3. Repository Structure for Django Passkey Project

Our Django project contains many files, but these are the most important ones:

├── .env # Contains all environment variables ├── passkeys_demo | ├── settings.py # Global settings | ├── urls.py # Route config | ├── views.py # Controller for our pages | ├── templates | | ├── index.html # Login page | | └── profile.html # Profile page

4. Set Up Your Corbado Account and Project

Visit the Corbado developer panel to sign up and create your account (you'll see the passkey sign-up in action here!).

Corbado Developer Panel Django

After sign-up, a project wizard will guide you through the necessary steps to get everything up and running:

  1. Begin by selecting an appropriate name for your project.
  2. For the product selection, opt for "Corbado Complete".
  3. Register your community license and optionally join our Passkeys Community or subscribe to the Passkeys Substack.
  4. Select "DEV" as your environment.
  5. Choose "Corbado session management" to get a secure and efficient session management besides passkey authentication.
  6. Choose "Web app" as we're building a web application.
  7. Select "Vanilla JS" as your frontend framework.
  8. Provide the Application URL and Relying Party ID. The Application URL is the URL where you embed the Corbado UI component. In this example, we set it to http://localhost:8000. The Relying Party ID is the domain (no protocol, no port and no path) where passkeys should be bound to. Here, it's localhost (you can define both values als in the Settings > General > URLs of the Corbado developer panel).

Afterwards, you'll see the relevant HTML / JavaScript code snippets you need to integrate into the project. The subsequent sections of this article will explain them in detail.

As another step, we create an API secret which will be needed to request user data from the Corbado backend. Please create an API secret in Settings > Credentials > API secrets.

Corbado Developer Panel: Create API Secret

5. Django Passkey Project Setup

5.1 Initialize Project

If you haven't installed Django yet, do so by executing

pip install Django==4.2.7

Install the latest version of the Corbado Python SDK (passkeys):

pip install passkeys

To initialize our project, we create a new Django project with

django-admin startproject passkeys_demo

This will create a passkeys_demo folder containing our Django project.

5.2 Configure Environment Variables

We head into our project with

cd passkeys_demo

and create a .env file in the passkeys_demo subfolder with the following contents (using your own values of course):

PROJECT_ID=pro-xxx API_SECRET=corbado1_xxx

We use environ to load the key-value pairs from the .env file into our environment variables. Install it with

pip install django-environ

Then, we can import it in our passkeys_demo/settings.py file and use it to obtain the variables from `.env and add them as actual environment variables in Django:

import environ env = environ.Env() environ.Env.read_env() PROJECT_ID = env('PROJECT_ID') API_SECRET = env('API_SECRET')

5.3 Create Templates With Session Management

Our templates are placed in passkeys_demo/templates (You must create the templates folder first). The login page will be in passkeys_demo/templates/index.html. It contains a script from Corbado as well as the Corbado UI component:

<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/@corbado/web-js@latest/dist/bundle/index.css" /> <script src="https://unpkg.com/@corbado/web-js@latest/dist/bundle/index.js"></script> <body> <script> (async () => { await Corbado.load({ projectId: "{{ PROJECT_ID }}", darkMode: "off", setShortSessionCookie: "true", //set short session cookie automatically }); const authElement = document.getElementById('corbado-auth'); //Element where you want to render CorbadoAuth UI Corbado.mountAuthUI(authElement, { onLoggedIn: () => { //post login actions can be performed here. window.location.href = '/profile'; }, }); })(); </script> <div id="corbado-auth"></div> </body> </html>

Our second page is the profile page where the user will be redirected to after authentication. Here, we show some basic user info which we will obtain in the controller beforehand (we will create the controller later). We also provide a logout button which will terminate the session Corbado had initiated after authentication. The page is located at passkeys_demo/templates/profile.html with the following content:

<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/@corbado/web-js@latest/dist/bundle/index.css" /> <script src="https://unpkg.com/@corbado/web-js@latest/dist/bundle/index.js"></script> </head> <body> <!-- Define passkey-list div and logout button --> <h2>:/protected 🔒</h2> <p>User ID: {{USER_ID}}</p> <p>Name: {{USER_NAME}}</p> <p>Email: {{USER_EMAIL}}</p> <div id="passkey-list"></div> <button id="logoutButton">Logout</button> <!-- Script to load Corbado and mount PasskeyList UI --> <script> (async () => { await Corbado.load({ projectId: "{{ PROJECT_ID }}", darkMode: "off", setShortSessionCookie: "true" // set short session cookie automatically }); // Get and mount PasskeyList UI const passkeyListElement = document.getElementById("passkey-list"); // Element where you want to render PasskeyList UI Corbado.mountPasskeyListUI(passkeyListElement); // Get logout button const logoutButton = document.getElementById('logoutButton'); // Add event listener to logout button logoutButton.addEventListener('click', function() { Corbado.logout() .then(() => { window.location.replace("/"); }) .catch(err => { console.error(err); }); }); })(); </script> </body> </html>

5.4 Create Django Controller and Configure Routes

We will now create the controller for the pages we created a step earlier. In the passkeys_demo folder create a views.py file. It needs two methods: one for the index page and one for the profile page. Inside the index method, we only need to inject the Project ID, but inside the profile method, we need to verify the integrity of the Corbado session and extract the data stored in it. For this, we use the Corbado Python SDK sessions service:

The views.py file should look like this:

from typing import List from corbado_python_sdk import Config, CorbadoSDK, SessionInterface, UserEntity from corbado_python_sdk.entities.session_validation_result import ( SessionValidationResult, ) from corbado_python_sdk.generated.models.identifier import Identifier from corbado_python_sdk.services.interface.identifier_interface import ( IdentifierInterface, ) from django.http import HttpResponse from django.shortcuts import redirect, render from passkeys_demo.settings import API_SECRET, PROJECT_ID # Config has a default values for 'short_session_cookie_name' and 'BACKEND_API' config: Config = Config( api_secret=API_SECRET, project_id=PROJECT_ID, ) # Initialize SDK sdk: CorbadoSDK = CorbadoSDK(config=config) sessions: SessionInterface = sdk.sessions identifiers: IdentifierInterface = sdk.identifiers def index(request) -> HttpResponse: context = { "PROJECT_ID": PROJECT_ID, } return render(request, "index.html", context) def profile( request, ) -> HttpResponse: token = request.COOKIES.get(config.short_session_cookie_name) try: if not token: raise ValueError("No token found") validation_result: SessionValidationResult = ( sessions.get_and_validate_short_session_value(short_session=token) ) if validation_result.authenticated: email_identifiers: List[Identifier] = ( identifiers.list_all_emails_by_user_id( user_id=validation_result.user_id or "" # at this point user_id should be non empty string since user was authenticated ) ) user: UserEntity = sessions.get_current_user(short_session=token) context = { "request": request, "PROJECT_ID": PROJECT_ID, "USER_ID": user.user_id, "USER_NAME": user.full_name, "USER_EMAIL": email_identifiers[0].value, } return render(request, "profile.html", context) else: return HttpResponse( "You are not authenticated or have not yet confirmed your email.", status=401, ) except Exception as e: print(e) return redirect("/")

As a last step, we configure the routes for the two methods. Inside passkeys_demo/urls.py, we set a route for the login page and one for the profile page as well as a redirect for any other route:

from django.urls import path from . import views from django.shortcuts import redirect urlpatterns = [ path("", views.index, name="index"), path("profile/", views.profile, name="profile"), path('<path:unknown_path>/', lambda request, unknown_path: redirect('/'), name='fallback') ]
Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

6. Run Django Application

Now, run your Django application using the following command:

python manage.py runserver

Your Django application will start and when visiting http://localhost:8000 with a web browser, you should see the Corbado UI component:

django passkeys ui component

After successful sign-up / login, you see the profile page:

passkey profile page

7. Conclusion

This tutorial showed how easy it is to add passwordless authentication with passkeys to a Django app with using Corbado. Besides the passkey-first authentication, Corbado provides simple session management, that we used for a retrieval of basic user data. If you want to read more about how Corbado's session management please check the docs here.

Share this article


LinkedInTwitterFacebook

Table of Contents

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free