Skip to main content

Authera — Django Authentication (Clerk‑style)

Authera is a modern authentication and user management package for Django that enables Clerk‑style, step‑based auth flows using Django REST Framework and SimpleJWT.

Key features

  • Pluggable, multi‑step authentication scenarios
  • First‑class Django REST Framework endpoints
  • JWT issuance and refresh via djangorestframework‑simplejwt
  • Stateless step tracking using Django cache
  • Minimal, extensible building blocks for custom auth UX

Requirements

  • Python >= 3.9
  • Django >= 4.2
  • djangorestframework >= 3.15
  • djangorestframework-simplejwt >= 5.3.0

Installation

pip install authera

Or install from source in editable mode:

pip install -e .

Quickstart

  1. Add apps to INSTALLED_APPS:
INSTALLED_APPS = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "rest_framework",
    "rest_framework_simplejwt",
    "authera",
]
  1. Configure DRF + SimpleJWT (recommended):
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
}

from datetime import timedelta

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=15),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=7),
}
  1. Define your user step scenarios:

Authera ships with a simple username/password scenario you can start with. You can add more scenarios or implement your own later.

# settings.py
from authera.scenario import UsernamePasswordScenario

USER_STEP_SCENARIO = [
    # name, key, and TTL (seconds) for the next‑step state per user
    UsernamePasswordScenario(
        name="Username & Password",
        key="username-password",
        each_user_TTL=300,
    ),
]
  1. Wire up URLs:
# urls.py
from django.urls import path, include

urlpatterns = [
    path("auth/", include("authera.urls")),
]

Available endpoints

Base path assumes auth/ as shown above.

  • GET auth/options/
    • Returns the available scenarios and their JSON Schemas for client‑side validation and rendering.
  • POST auth/validate/<scenario_key>
    • Validates user input for the given scenario step. If it is the final step, returns tokens and user info. Otherwise returns a signed payload and user_id, and advances the user to the next step.
  • POST auth/refresh/
    • Exchanges a valid refresh token for new access and refresh tokens.

Request/response examples

  1. Get available options (schemas):
curl -X GET http://localhost:8000/auth/options/

Example response:

{
  "username-password": {
    "type": "object",
    "properties": {
      "username": { "type": "string", "minLength": 3, "maxLength": 255 },
      "password": { "type": "string", "minLength": 8, "maxLength": 255 }
    },
    "required": ["username", "password"]
  }
}
  1. Validate a step (username‑password):
curl -X POST http://localhost:8000/auth/validate/username-password \
  -H "Content-Type: application/json" \
  -d '{
    "options": { "username": "alice", "password": "S3cretPass!" }
  }'

If this is the final step, you’ll receive tokens and user info:

{
  "access_token": "<jwt>",
  "refresh_token": "<jwt>",
  "token_type": "Bearer",
  "expires_in": 900,
  "user": {
    "id": 1,
    "username": "alice",
    "permits": ["staff", "editor"]
  }
}
  1. Refresh tokens:
curl -X POST http://localhost:8000/auth/refresh/ \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "<jwt>"
  }'

Response:

{
  "access_token": "<new_access_jwt>",
  "refresh_token": "<new_refresh_jwt>",
  "token_type": "Bearer",
  "expires_in": 900
}

Extending: create a custom scenario

Implement your own step by subclassing BaseScenario and adding it to USER_STEP_SCENARIO.

from rest_framework.response import Response
from authera.utils import BaseScenario

class EmailOtpScenario(BaseScenario):
    schema = {
        "type": "object",
        "properties": { "email": { "type": "string", "format": "email" }, "otp": { "type": "string" } },
        "required": ["email", "otp"]
    }

    def __init__(self):
        super().__init__(name="Email OTP", key="email-otp", each_user_TTL=300)

    def validate(self, user_payload, scenario_options) -> Response:
        # Validate OTP for the provided email; return 200 to advance, otherwise non‑200
        return Response()

    def get_user(self, user_id, options):
        # Return a Django user instance when this is the last step
        ...

Security notes

  • Always use HTTPS in production.
  • Configure reasonable lifetimes for access and refresh tokens.
  • Consider rotating refresh tokens and revocation strategies depending on risk profile.
  • Ensure cache backend is correctly configured for step‑state tracking.

Development

Run a local Django project that includes authera, then exercise the endpoints with the examples above.

Contributing

Issues and PRs are welcome. Please open an issue to discuss substantial changes first.

License

MIT © Algonouir

Metadata

Release files for authera 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for authera 1.1.2
File Size Uploaded
authera-1.1.2.tar.gz 20.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for authera 1.1.2
File Interpreter ABI Platform
authera-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 41.2 kB

Release files / authera-1.1.2.tar.gz

Download URL authera-1.1.2.tar.gz
Size 20.9 kB
Tags Source
SHA-256 checksum
How to use checksums
cc67821e40e6f83757ba163add83003c0c522f441d8b9c2a5db3d603d4c9cd4c
BLAKE2b-256 checksum
How to use checksums
bf41c0dcb7e00bfb859302802b9f282795e3c4987be3aa3a3e4a355987fb71b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.12

Release files / authera-1.1.2-py3-none-any.whl

Download URL authera-1.1.2-py3-none-any.whl
Size 20.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9f94456764b8658ba532357f85ee33db4100d6f09246b6ef5558674f83ca26f6
BLAKE2b-256 checksum
How to use checksums
63eef6a53cd7edbc0ebfa1732a79ea7667dc620c375ad32971096e48d55b4652
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.12

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page