Skip to main content

django-channels-jwt-stateless

Stateless JWT authentication middleware for Django Channels. Zero database queries on WebSocket handshake.

Existing Django Channels JWT packages call User.objects.get() on every WebSocket connect. Under burst traffic this saturates the connection pool and causes multi-second stalls. This package verifies the JWT signature and builds a lightweight HandshakeUser from the token claims instead.

Install

pip install django-channels-jwt-stateless

Quick Start

# asgi.py
from channels.routing import ProtocolTypeRouter, URLRouter
from django_channels_jwt_stateless import JWTAuthMiddlewareStack

application = ProtocolTypeRouter({
    "http": django_application,
    "websocket": JWTAuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
})

Works out of the box with djangorestframework-simplejwt defaults (HS256, SECRET_KEY, user_id claim). Pass the token as ?token=<jwt> in the WebSocket URL.

scope["user"]

On a valid token, scope["user"] is a HandshakeUser instance:

Attribute Value
.id / .pk From the JWT user_id claim
.is_anonymous False
.is_authenticated True

On an invalid, expired, or missing token it is AnonymousUser.

Configuration

Optional. Add to settings.py:

CHANNELS_JWT_STATELESS = {
    "ALGORITHM": "HS256",              # default
    "SIGNING_KEY": None,               # defaults to SECRET_KEY
    "USER_ID_CLAIM": "user_id",        # default
    "TOKEN_QUERY_PARAM": "token",      # default
    "IS_BLACKLISTED": None,            # dotted path to (jti) -> bool
    "TOKEN_DECODER": None,             # dotted path to (token) -> dict
    "SUBPROTOCOL_PREFIX": None,        # e.g. "access_token"
}

TOKEN_DECODER and IS_BLACKLISTED accept both sync and async callables.

Token Blacklisting

# myapp/auth.py
from django.core.cache import cache

async def is_blacklisted(jti: str) -> bool:
    return await cache.aget(f"blacklist:{jti}") is not None

# settings.py
CHANNELS_JWT_STATELESS = {
    "IS_BLACKLISTED": "myapp.auth.is_blacklisted",
}

Subprotocol Auth

To avoid leaking tokens in query strings:

CHANNELS_JWT_STATELESS = {"SUBPROTOCOL_PREFIX": "access_token"}

Client sends Sec-WebSocket-Protocol: access_token.<jwt>.

Compatibility

Python 3.10+, Django 4.2+, Channels 4+, PyJWT 2+.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_channels_jwt_stateless-0.1.1.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_channels_jwt_stateless-0.1.1-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file django_channels_jwt_stateless-0.1.1.tar.gz.

File metadata

File hashes

Hashes for django_channels_jwt_stateless-0.1.1.tar.gz
Algorithm Hash digest
SHA256 21e6a22f29c32e4af0088ee063a23a45edb06756cdbce0dee4fc82aca944cd7e
MD5 0342801e77b98b52ba8ab37b0ec7a7fa
BLAKE2b-256 e23af4123960e5ff26396ee554725bb7473bbc39839430e69dee608c571d9544

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_channels_jwt_stateless-0.1.1.tar.gz:

Publisher: publish.yml on zxzinn/django-channels-jwt-stateless

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_channels_jwt_stateless-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_channels_jwt_stateless-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 366f06b22ecf09553611f0026ff6907a29b29fe573a6da8b361fa44b4211f452
MD5 4b28230e812a171ff8e9edc28dfca46a
BLAKE2b-256 9ef4b90ab4944795de07dd7cce3a7e7428c0e056691db9c97d762cbd9b55c877

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_channels_jwt_stateless-0.1.1-py3-none-any.whl:

Publisher: publish.yml on zxzinn/django-channels-jwt-stateless

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 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