Skip to main content

JWT authentication using HTTP-only cookies for Django REST Framework

Project description

Django Cookie JWT

codecov Mypy Checked Python Version PyPI version License

JWT authentication using HTTP-only cookies for Django REST Framework.

Overview

This plugin provides secure JWT authentication by storing tokens in HTTP-only cookies instead of local storage or headers. This approach reduces XSS risks and simplifies frontend authentication handling.

Features

  • HTTP-only cookies: Tokens stored securely in browser cookies
  • Automatic token refresh: Middleware handles token renewal transparently
  • Fallback authentication: Supports both cookie and header-based authentication
  • Session cookie support: Optional Django session cookie creation
  • OpenAPI integration: Automatic API documentation with drf-spectacular
  • Customizable settings: Flexible cookie configuration options

Installation

pip install django-cookiejwt

Quick Setup

  1. Add to INSTALLED_APPS:
INSTALLED_APPS = [
    # ... other apps
    'rest_framework',
    'rest_framework_simplejwt',
    'rest_framework_simplejwt.token_blacklist',
    'django_cookiejwt',
]
  1. Add middleware:
MIDDLEWARE = [
    # ... other middleware
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django_cookiejwt.middlewares.RefreshTokenMiddleware',
    # ... other middleware
]
  1. Configure authentication:
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'django_cookiejwt.authentication.CookieJWTAuthentication',
    ],
}
  1. Include URLs:
from django.urls import path, include

urlpatterns = [
    # ... your urls
    path('api/auth/', include('django_cookiejwt.urls')),
]

Configuration

Configure cookie behavior in your Django settings:

# Cookie security settings
COOKIEJWT_HTTPONLY = True          # HTTP-only cookies (recommended)
COOKIEJWT_SECURE = True           # Set to False in development!
COOKIEJWT_SAMESITE = 'Lax'         # CSRF protection

# Cookie naming and expiration
COOKIEJWT_ACCESS_MAX_AGE = 300     # 5 minutes
COOKIEJWT_REFRESH_MAX_AGE = 86400  # 1 day
COOKIEJWT_PATH = '/'
COOKIEJWT_DOMAIN = None

# Session cookie creation
COOKIEJWT_SET_SESSION_COOKIE = True

Production Configuration

Important: The default settings are NOT secure for production use. Configure these settings before deploying:

# Production security settings
COOKIEJWT_SECURE = True            # REQUIRED: HTTPS only
COOKIEJWT_SAMESITE = 'Strict'      # RECOMMENDED: Strong CSRF protection
COOKIEJWT_HTTPONLY = True          # REQUIRED: Prevent XSS attacks

# Optional production optimizations
COOKIEJWT_DOMAIN = 'yourdomain.com'  # Restrict to your domain

Critical: Never use COOKIEJWT_SECURE = False in production. This will send tokens over unencrypted HTTP connections, creating a serious security vulnerability.

Authentication Behavior

The authentication system works with a fallback mechanism:

  1. Cookie Authentication (Primary): The system first looks for JWT tokens in HTTP-only cookies
  2. Header Authentication (Fallback): If no valid token is found in cookies, it falls back to standard JWT header authentication (Authorization: Bearer <token>)

This means you can use both authentication methods simultaneously:

  • Frontend applications can use cookies for seamless authentication
  • API clients and mobile apps can use traditional header-based authentication

Performance Considerations

The RefreshTokenMiddleware processes every request (except /admin/ paths) and performs the following operations:

  • Reads and validates access token from cookies
  • Makes database queries to authenticate users
  • Automatically refreshes expired tokens when possible

This provides seamless user experience but adds processing overhead to each request. Consider this when designing high-traffic applications.

Usage

Authentication

Send login credentials to the token endpoint:

curl -X POST http://localhost:8000/api/auth/token/ \
  -H "Content-Type: application/json" \
  -d '{"username": "user", "password": "pass"}'

The response will set HTTP-only cookies containing JWT tokens.

Header-based Authentication

Traditional JWT authentication also works:

curl -X GET http://localhost:8000/api/protected-endpoint/ \
  -H "Authorization: Bearer <your-jwt-token>"

Logout

Blacklist the refresh token:

curl -X POST http://localhost:8000/api/auth/token/blacklist/ \
  -H "Content-Type: application/json" \
  -d '{"refresh": ""}'

This will clear the authentication cookies.

Frontend Usage

With cookies set, authenticated requests work automatically:

// No need to handle tokens manually
fetch('/api/protected-endpoint/', {
  credentials: 'include'  // Include cookies
})

How It Works

  1. Login: User credentials are exchanged for JWT tokens stored in HTTP-only cookies
  2. Requests: Cookies are automatically sent with each request
  3. Authentication: System checks cookies first, then falls back to Authorization header
  4. Refresh: Middleware automatically refreshes expired access tokens using the refresh token
  5. Logout: Refresh token is blacklisted and cookies are cleared

Security Benefits

  • XSS Protection: HTTP-only cookies prevent JavaScript access to tokens
  • CSRF Mitigation: SameSite cookie attribute provides CSRF protection
  • Automatic Handling: No manual token management required on frontend
  • Flexible Integration: Supports both cookie and header authentication

API Endpoints

  • POST /api/auth/token/ - Obtain JWT tokens (login)
  • POST /api/auth/token/blacklist/ - Blacklist refresh token (logout)

Requirements

  • Django >= 4.0
  • Django REST Framework >= 3.14.0
  • djangorestframework-simplejwt >= 5.2.0
  • drf-spectacular >= 0.28.0
  • Python >= 3.12

License

MIT License

Contributing

Issues and pull requests are welcome on GitHub.

Project details


Download files

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

Source Distribution

django_cookiejwt-0.0.2.tar.gz (45.6 kB view details)

Uploaded Source

Built Distribution

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

django_cookiejwt-0.0.2-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file django_cookiejwt-0.0.2.tar.gz.

File metadata

  • Download URL: django_cookiejwt-0.0.2.tar.gz
  • Upload date:
  • Size: 45.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for django_cookiejwt-0.0.2.tar.gz
Algorithm Hash digest
SHA256 aa600fe45c174dee9d174227610d774faf48a59b1ce374bcb5a03f8cda7ca217
MD5 5a95ea405b69d87c3731e04ac42998ca
BLAKE2b-256 8721df92c833abd7c626b42b5a6a02f3d39dfda15d9aa533859cad0d396df539

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_cookiejwt-0.0.2.tar.gz:

Publisher: publish.yaml on muehlemann-popp/django-cookiejwt

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_cookiejwt-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for django_cookiejwt-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 edfca2190737ce633472ce2d04fe335877e4ad8c389e43a6feb9d4684b45f92e
MD5 2bf812c0b29a74be599b5e0350d9e174
BLAKE2b-256 2e369e3e9cdce5a39f7114ecd5d1be9b3447fc55a7857fc7115d7cd2cd90a179

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_cookiejwt-0.0.2-py3-none-any.whl:

Publisher: publish.yaml on muehlemann-popp/django-cookiejwt

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page