Passkeys Python Flask TutorialPasskeys Implementation

Flask Passkeys: How to Implement Passkeys with Python Flask

Passkeys in Python Flask: Secure your Flask applications with passkeys by following this tutorial for Python Flask developers.

Blog-Post-Author

Janina

Created: September 15, 2023

Updated: August 28, 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#

Passkeys are emerging as a passwordless and more secure way to log into websites. In this tutorial, we will learn how to use the Corbado UI components to implement passkey login functionality for a great user experience. Using Python and the Flask framework, we will build a login page that accepts passkeys to authenticate users. With just a few lines of code, you can add this cutting-edge login method to enable fast, simple, and secure access to your web app.

1. What we will build

The image below provides a preview of the passkey login page we will create by following the step-by-step instructions in this tutorial:

flask passkeys ui component

2. Python passkey project prerequisites

This tutorial is suitable for both beginners and experienced developers. To follow along, you'll need to have the following:

  • Have Python and pip installed
  • Basic knowledge of HTML, JavaScript, Python, and Flask - though you can still follow along even if you're new to these.

3. Repository structure for Python passkey project

For reference, the code snippet below outlines the directory structure of the Flask passkey app we will be coding in this tutorial. You can grab the full source code for the complete project from this GitHub URL. Copy the .env.example file and rename it to .env.

/FLASK-CORBADO /templates login.html home.html .env corbado-auth.py

Explanation:

  • /templates: This folder will contain the HTML templates for your login and home pages.
  • .env: This file will securely store the Corbado project ID.
  • corbado-auth.py: This is the main file where your Flask application will be defined.
Slack Icon

Become part of our Passkeys Community for updates and support.

Join

4. Flask project setup

Follow the steps below to set up your project:

  1. Create your project directory, here:
mkdir example-passkeys-python-flask-main
cd example-passkeys-python-flask-main
  1. Verify if pip is installed by running:
pip --version
  1. Finally, let's install the required packages, we will use pip to install Flask, python-dotenv, Corbado Python SDK (which is called passkeys within pip):
pip install flask python-dotenv passkeys

This will install:

  • Flask - A lightweight WSGI web application framework for Python
  • python-dotenv - For loading environment variables from a .env file
  • passkeys - Corbado SDK that provides straightforward access to Corbado services

5. Configure Corbado for Passkey Authentication

5.1 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 Flask

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 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:5000. The Relying Party ID is the domain (no protocol, no port, and no path) where passkeys should be bound. Here, it's localhost (you can define both values als in the Settings > General > URLs of the Corbado developer panel).

Afterwards, you will 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.2 Configure environment variables

In the .env file, you will store sensitive credentials like your API secret and project ID as environment variables. This is a security best practice to avoid hardcoding these values directly in your scripts. To get your API secret and project ID, visit your Corbado developer panel.

Please refer to the Corbado docs for more details on obtaining the necessary credentials and integrating Corbado authentication in your application.

.env
API_SECRET=enter_api_key PROJECT_ID=enter_project_id

5.3 Create Flask routes and load environment variables

Create the corbado-auth.py file, which holds our Flask app that integrates with Corbado for authentication. In this code, we loaded credentials from environment variables using python-dotenv. A Session class validates JWTs from cookies to determine the current user. The / route displays a login page, while /home shows the user's profile if authenticated, else raises Unauthorized.

Routes are protected by validating JWTs which are short-lived. JWT signatures are verified using public keys from a JWKS URI. The Session class handles JWT validation and protected routes grant access only to valid users. We use Corbado Python SDK (passkeys) to handle the session.

corbado-auth.py
from typing import List from corbado_python_sdk.entities.session_validation_result import ( SessionValidationResult, ) from corbado_python_sdk.generated.models.identifier import Identifier from flask import Flask, render_template, request from werkzeug.exceptions import Unauthorized from dotenv import load_dotenv import os from corbado_python_sdk import ( Config, CorbadoSDK, IdentifierInterface, UserEntity, SessionInterface, UserInterface, ) # Load environment variables from the .env file load_dotenv() app = Flask(__name__) PROJECT_ID: str = os.environ.get("PROJECT_ID") or "" API_SECRET: str = os.environ.get("API_SECRET") or "" # 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 users: UserInterface = sdk.users # Use the API_SECRET from the environment variables app.config["API_SECRET"] = API_SECRET # Pass PROJECT_ID as a context variable to templates app.config["PROJECT_ID"] = PROJECT_ID @app.route("/") def login() -> str: return render_template( template_name_or_list="login.html", PROJECT_ID=app.config["PROJECT_ID"] ) @app.route("/home") def home() -> str: # Acquire cookies with your preferred method token: str = request.cookies.get(config.short_session_cookie_name) or "" validation_result: SessionValidationResult = sessions.get_current_user( short_session=token ) if validation_result.authenticated: user: UserEntity = users.get(user_id=validation_result.user_id) email_identifiers: List[Identifier] = identifiers.list_all_emails_by_user_id( user_id=validation_result.user_id ) user_data = { "id": user.user_id, "name": user.full_name, "email": email_identifiers[0].value, } return render_template( template_name_or_list="home.html", user_data=user_data, PROJECT_ID=app.config["PROJECT_ID"], ) else: raise Unauthorized() if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)

5.4 Create templates with session management

Now, create HTML templates for the login and home pages. The project ID will be dynamically inserted into these templates using the Jinja2 template engine, which is integrated with Flask.

5.4.1 Login Page (login.html)

Copy and paste these codes in the templates/login.html file to create the login page using the Corbado UI component:

templates/login.html
<!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 = '/home'; }, }); })(); </script> <div id="corbado-auth"></div> </body> </html>

5.4.2 Home Page (home.html)

Now, we create our protected home page, visible only after user authentication and validation. It showcases user details and incorporates the Corbado Python SDK (passkeys) for authentication, allowing users to log out with a simple button click.

templates/home.html
<!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_data.id }}</p> <p>Name: {{ user_data.name }}</p> <p>Email: {{ user_data.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 the 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>

In both templates, the PROJECT_ID is dynamically inserted using {{ PROJECT_ID }} to include the project ID from the environment variables.

5.5 Run the Flask application

Now, run your Flask application using the following command in the terminal:

python corbado-auth.py

flask passkeys ui component

Your Flask application will start, and you can open a web browser to visit http://localhost:5000 to see your login page.

flask passkey list

After a successful login and session validation, you should be redirected to the home page where you can see some user data and the logout button as shown in the image above.

Flask Icon

Add passkeys to your Flask app.

Start For Free

6. Conclusion

Implementing passkey authentication creates a seamless and secure login experience for users, removing the vulnerabilities of passwords. This tutorial showed how to easily integrate passkeys into a Flask app using Corbado.

With just a few lines of Python code, we built a login page that accepts passkeys for authentication. Passkeys represent are the new standard of login, eliminating phishing and breaches tied to reused passwords. By following this guide, you can add cutting-edge passkey support to your own Flask apps and take a step towards a passwordless web.

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