JWT authentication using HTTP-only cookies for Django REST Framework
Project description
Django Cookie JWT
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
- Add to
INSTALLED_APPS:
INSTALLED_APPS = [
# ... other apps
'rest_framework',
'rest_framework_simplejwt',
'rest_framework_simplejwt.token_blacklist',
'django_cookiejwt',
]
- Add middleware:
MIDDLEWARE = [
# ... other middleware
'django.contrib.sessions.middleware.SessionMiddleware',
'django_cookiejwt.middlewares.RefreshTokenMiddleware',
# ... other middleware
]
- Configure authentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'django_cookiejwt.authentication.CookieJWTAuthentication',
],
}
- 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:
- Cookie Authentication (Primary): The system first looks for JWT tokens in HTTP-only cookies
- 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
- Login: User credentials are exchanged for JWT tokens stored in HTTP-only cookies
- Requests: Cookies are automatically sent with each request
- Authentication: System checks cookies first, then falls back to Authorization header
- Refresh: Middleware automatically refreshes expired access tokens using the refresh token
- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters