JSON Web Token based authentication for Django REST framework
—
JWT authentication backend classes that integrate with Django REST Framework's authentication system to validate JWTs and authenticate users from HTTP requests.
Abstract base class providing core JWT authentication logic that can be extended for different JWT extraction methods.
class BaseJSONWebTokenAuthentication(BaseAuthentication):
def authenticate(self, request):
"""
Returns a two-tuple of (User, token) if valid JWT authentication
is provided, otherwise returns None.
Args:
request: HTTP request object
Returns:
tuple: (User instance, JWT token string) or None
Raises:
AuthenticationFailed: For expired, invalid, or malformed tokens
"""
def authenticate_credentials(self, payload):
"""
Returns an active user that matches the payload's username.
Args:
payload (dict): Decoded JWT payload containing user information
Returns:
User: Active user instance
Raises:
AuthenticationFailed: If user not found, inactive, or invalid payload
"""
def get_jwt_value(self, request):
"""
Extract JWT value from request. Base implementation returns None.
Must be overridden by subclasses to provide actual token extraction.
Args:
request: HTTP request object
Returns:
str: JWT token string or None if not found
Note:
Base implementation returns None. Subclasses must override this
method to implement specific token extraction logic.
"""Complete JWT authentication implementation that extracts tokens from Authorization headers or cookies.
class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
www_authenticate_realm = 'api'
def get_jwt_value(self, request):
"""
Extracts JWT from Authorization header or cookie.
Header format: 'Authorization: JWT <token>'
Cookie: Configurable via JWT_AUTH_COOKIE setting
Args:
request: HTTP request object
Returns:
str: JWT token string or None if not found
Raises:
AuthenticationFailed: For malformed Authorization headers
"""
def authenticate_header(self, request):
"""
Returns WWW-Authenticate header value for 401 responses.
Args:
request: HTTP request object
Returns:
str: WWW-Authenticate header value
"""# In Django settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
],
}
# Optional: Configure JWT settings
JWT_AUTH = {
'JWT_AUTH_HEADER_PREFIX': 'Bearer', # Change from default 'JWT'
'JWT_AUTH_COOKIE': 'jwt-token', # Enable cookie-based auth
}from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
class CustomJWTAuthentication(BaseJSONWebTokenAuthentication):
def get_jwt_value(self, request):
# Extract JWT from custom header
return request.META.get('HTTP_X_JWT_TOKEN')
def authenticate_credentials(self, payload):
# Add custom user validation logic
user = super().authenticate_credentials(payload)
# Additional checks
if not user.profile.is_api_enabled:
raise AuthenticationFailed('API access disabled')
return userfrom rest_framework.views import APIView
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class ProtectedView(APIView):
authentication_classes = [JSONWebTokenAuthentication]
def get(self, request):
# request.user is authenticated via JWT
return Response({'user': request.user.username})The authentication classes raise AuthenticationFailed exceptions for various error conditions:
from rest_framework.exceptions import AuthenticationFailed
# Common authentication errors:
# - "Signature has expired" (jwt.ExpiredSignature)
# - "Error decoding signature" (jwt.DecodeError)
# - "Invalid payload" (missing/invalid username)
# - "Invalid signature" (user not found)
# - "User account is disabled" (inactive user)
# - "Invalid Authorization header" (malformed header format)These exceptions are automatically converted to HTTP 401 Unauthorized responses by Django REST Framework.
The authentication module defines handler function references used by authentication classes:
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
"""Function reference for decoding JWT tokens."""
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER
"""Function reference for extracting username from JWT payload."""The authentication classes integrate seamlessly with Django REST Framework's authentication pipeline:
authenticate() method for each configured authentication classrequest.user and request.auth are setThe authentication classes rely on settings from rest_framework_jwt.settings:
JWT_DECODE_HANDLER: Function to decode JWT tokensJWT_PAYLOAD_GET_USERNAME_HANDLER: Function to extract username from payloadJWT_AUTH_HEADER_PREFIX: Prefix for Authorization header (default: 'JWT')JWT_AUTH_COOKIE: Cookie name for token storage (optional)Install with Tessl CLI
npx tessl i tessl/pypi-djangorestframework-jwt