Skip to main content

JWT authentication using HTTP-only cookies for Django REST Framework

Project description

Django Cookie JWT

codecov Python 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 = False           # Set to True in production!
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.1.tar.gz (43.7 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.1-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_cookiejwt-0.0.1.tar.gz
  • Upload date:
  • Size: 43.7 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.1.tar.gz
Algorithm Hash digest
SHA256 1a962746ab9d265ed8defc4fd82ab67f741e3a09e8ac4737b4ef312e40f2a9a8
MD5 f233e20b278fa7e41d45460687132c9d
BLAKE2b-256 c28f395545dc81d99cec1a74cccc227ebe64eb53c4876eacbe4ab6c5d5ac896f

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_cookiejwt-0.0.1.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.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_cookiejwt-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ff453c2b7cbbaa937c595a51483b8fddd6773b720eb5407058639ebe9542ac47
MD5 2fdf79a151cf3c74c8b94ba6180df26e
BLAKE2b-256 8ebf237655ed35637003bfc87d550d3f2dfbd35073b3cb9b4d5057db6f2fcbd1

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_cookiejwt-0.0.1-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