or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

admin-interface.mdcore-authentication.mddevice-models.mddjango-integration.mdemail-devices.mdhotp-devices.mdindex.mdoath-algorithms.mdstatic-tokens.mdtotp-devices.md
tile.json

tessl/pypi-django-otp

A pluggable framework for adding two-factor authentication to Django using one-time passwords.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/django-otp@1.6.x

To install, run

npx @tessl/cli install tessl/pypi-django-otp@1.6.0

index.mddocs/

Django OTP

A pluggable framework for adding two-factor authentication to Django applications using one-time passwords. Django-otp provides a comprehensive solution for implementing multi-factor authentication with support for HOTP (RFC 4226), TOTP (RFC 6238), email-based tokens, and static backup codes.

Package Information

  • Package Name: django-otp
  • Language: Python
  • Installation: pip install django-otp
  • Django Version: 4.2+
  • Python Version: 3.7+

Core Imports

import django_otp
from django_otp import login, verify_token, match_token, devices_for_user, user_has_device, device_classes, DEVICE_ID_SESSION_KEY
from django_otp.util import random_hex, random_number_token, hex_validator
from django_otp.qr import write_qrcode_image

For specific plugins:

from django_otp.plugins.otp_totp.models import TOTPDevice
from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
from django_otp.plugins.otp_email.models import EmailDevice
from django_otp.plugins.otp_hotp.models import HOTPDevice

For forms and views:

from django_otp.forms import OTPAuthenticationForm, OTPTokenForm
from django_otp.views import LoginView
from django_otp.decorators import otp_required
from django_otp.middleware import OTPMiddleware, is_verified

Basic Usage

Basic Setup and Device Management

from django_otp import devices_for_user, user_has_device
from django_otp.plugins.otp_totp.models import TOTPDevice
from django.contrib.auth.models import User

# Check if user has any OTP devices
user = User.objects.get(username='alice')
has_device = user_has_device(user)

# Get all devices for a user
devices = list(devices_for_user(user))

# Create a TOTP device for a user
device = TOTPDevice.objects.create(
    user=user,
    name='My Authenticator',
    confirmed=True
)

# Generate a QR code URL for device setup
config_url = device.config_url

Token Verification

from django_otp import verify_token

# Verify a token against a specific device
device = verify_token(user, device.persistent_id, '123456')
if device:
    print(f"Token verified with device: {device.name}")
else:
    print("Token verification failed")

Using OTP in Views

from django_otp.decorators import otp_required
from django.shortcuts import render

@otp_required
def secure_view(request):
    # This view requires OTP verification
    return render(request, 'secure_page.html')

# Check if user is OTP verified
from django_otp.middleware import is_verified

def my_view(request):
    if is_verified(request.user):
        # User is verified with OTP
        pass

Architecture

Django-otp is built around a plugin architecture with several key components:

  • Core Framework: Provides the base Device model and common functionality
  • Device Plugins: Implement specific OTP methods (TOTP, HOTP, Email, Static)
  • Django Integration: Forms, views, middleware, and admin interfaces
  • Security Features: Throttling, cooldowns, and drift compensation

The Device abstract model serves as the foundation, with concrete implementations provided by plugins. Each device can generate challenges and verify tokens, with built-in security features like rate limiting and cooldown periods.

Capabilities

Core Authentication API

Core functions for managing OTP authentication, including user login, token verification, and device management. These functions form the foundation of django-otp's authentication system.

def login(request, device):
    """
    Persist the given OTP device in the current session.
    
    Args:
        request: The HTTP request
        device: The OTP device used to verify the user
    """

def verify_token(user, device_id, token):
    """
    Attempts to verify a token against a specific device.
    
    Args:
        user: The user supplying the token
        device_id: A device's persistent_id value
        token: An OTP token to verify
        
    Returns:
        The device that accepted token, if any, or None
    """

def match_token(user, token):
    """
    Attempts to verify a token on every device attached to the user.
    
    Warning: Use of this function is no longer recommended.
    
    Args:
        user: The user supplying the token
        token: An OTP token to verify
        
    Returns:
        The device that accepted token, if any, or None
    """

def devices_for_user(user, confirmed=True, for_verify=False):
    """
    Return an iterable of all devices registered to the given user.
    
    Args:
        user: Standard or custom user object
        confirmed: If None, all devices returned; otherwise filter by confirmed status
        for_verify: If True, load devices with select_for_update
        
    Returns:
        Iterable of Device objects
    """

def user_has_device(user, confirmed=True):
    """
    Return True if the user has at least one device.
    
    Args:
        user: Standard or custom user object  
        confirmed: If None, all devices considered; otherwise filter by confirmed status
        
    Returns:
        Boolean indicating if user has devices
    """

def device_classes():
    """
    Returns an iterable of all loaded device models.
    
    Returns:
        Iterable of Device model classes
    """

Core Authentication

Device Models and Management

Abstract base models and mixins that provide the foundation for all OTP devices, including security features like throttling and cooldowns.

class Device(models.Model): ...
class SideChannelDevice(Device): ...
class CooldownMixin: ...
class ThrottlingMixin: ...

Device Models

TOTP (Time-based OTP)

Time-based one-time passwords following RFC 6238, typically used with authenticator apps like Google Authenticator or Authy.

class TOTPDevice(TimestampMixin, ThrottlingMixin, Device):
    key = models.CharField(max_length=80)
    step = models.PositiveSmallIntegerField(default=30)
    t0 = models.BigIntegerField(default=0)
    digits = models.PositiveSmallIntegerField(choices=[(6, 6), (8, 8)], default=6)
    tolerance = models.PositiveSmallIntegerField(default=1)
    drift = models.SmallIntegerField(default=0)
    last_t = models.BigIntegerField(default=-1)

TOTP Devices

HOTP (Counter-based OTP)

HMAC-based one-time passwords following RFC 4226, using a counter that increments with each use.

class HOTPDevice(TimestampMixin, ThrottlingMixin, Device):
    key = models.CharField(max_length=80)
    digits = models.PositiveSmallIntegerField(choices=[(6, 6), (8, 8)], default=6)
    tolerance = models.PositiveSmallIntegerField(default=5)
    counter = models.BigIntegerField(default=0)

HOTP Devices

Email-based OTP

One-time passwords delivered via email, useful for users who don't have smartphone access to authenticator apps.

class EmailDevice(TimestampMixin, CooldownMixin, ThrottlingMixin, SideChannelDevice):
    email = models.EmailField(blank=True)

Email Devices

Static Backup Tokens

Pre-generated backup codes for emergency access when primary OTP devices are unavailable.

class StaticDevice(TimestampMixin, ThrottlingMixin, Device): ...
class StaticToken(models.Model):
    device = models.ForeignKey(StaticDevice, on_delete=models.CASCADE)
    token = models.CharField(max_length=16)

Static Tokens

Django Integration

Forms, views, middleware, and decorators for integrating OTP authentication into Django applications.

class OTPAuthenticationForm(OTPAuthenticationFormMixin, AuthenticationForm): ...
class OTPTokenForm(OTPAuthenticationFormMixin, forms.Form): ...
class LoginView(auth_views.LoginView): ...
def otp_required(view=None, redirect_field_name='next', login_url=None, if_configured=False): ...
class OTPMiddleware: ...

Django Integration

Admin Interface

Admin classes and forms for managing OTP devices through Django's admin interface.

class OTPAdminSite(admin.AdminSite): ...
class OTPAdminAuthenticationForm(AdminAuthenticationForm, OTPAuthenticationFormMixin): ...

Admin Interface

OATH Algorithms

Low-level implementations of HOTP and TOTP algorithms for direct use or custom device implementations.

def hotp(key, counter, digits=6): ...
def totp(key, step=30, t0=0, digits=6, drift=0): ...
class TOTP: ...

OATH Algorithms

QR Code Generation

Utility for generating QR codes for device setup, supporting both qrcode and segno libraries.

def write_qrcode_image(data, out):
    """
    Write a QR code image for data to out in SVG format.
    
    Args:
        data: Data to encode in QR code
        out: Output stream to write SVG image
        
    Raises:
        ModuleNotFoundError: If neither qrcode nor segno is available
    """

Utilities and Validation

Helper functions for generating secure tokens and validating hex-encoded data.

def random_hex(length: int = 20) -> str:
    """
    Returns a string of random bytes encoded as hex.
    
    Args:
        length: The number of (decoded) bytes to return
        
    Returns:
        A string of hex digits
    """

def random_number_token(length: int = 6) -> str:
    """
    Returns a string of random digits.
    
    Args:
        length: The number of digits to return
        
    Returns:
        A string of decimal digits
    """

def hex_validator(length: int = 0):
    """
    Returns a function to validate hex-encoded CharField values.
    
    Args:
        length: If > 0, validation fails unless decoded value is exactly this many bytes
        
    Returns:
        Validator function for use in model fields
    """

Middleware Functions

Utility functions for checking OTP verification status.

def is_verified(user) -> bool:
    """
    Check if a user has been verified with OTP.
    
    Args:
        user: User object to check
        
    Returns:
        True if user.otp_device is not None
    """

Constants

DEVICE_ID_SESSION_KEY = 'otp_device_id'  # Session key for storing device ID

Common Types

# Device verification states
class GenerateNotAllowed(enum.Enum):
    """Enum for reasons why token generation is not allowed."""
    COOLDOWN_DURATION_PENDING = 'COOLDOWN_DURATION_PENDING'

class VerifyNotAllowed(enum.Enum):
    """Enum for reasons why token verification is not allowed."""
    N_FAILED_ATTEMPTS = 'N_FAILED_ATTEMPTS'

# Settings wrapper
class Settings:
    """Settings object for django-otp configuration."""
    def __getattr__(self, name): ...

# Device manager
class DeviceManager(models.Manager):
    """Manager for Device models."""
    def devices_for_user(self, user, confirmed=None): ...

# Model mixins
class CooldownMixin(models.Model):
    """Mixin that provides cooldown functionality for devices."""
    class Meta:
        abstract = True

class ThrottlingMixin(models.Model):
    """Mixin that provides throttling functionality for devices."""
    class Meta:
        abstract = True

class TimestampMixin(models.Model):
    """Mixin that provides timestamp tracking for devices."""
    class Meta:
        abstract = True