CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-djangorestframework-jwt

JSON Web Token based authentication for Django REST framework

Pending
Overview
Eval results
Files

serializers.mddocs/

Serializers

Validation and processing classes for JWT authentication workflows, handling user credentials, token verification, and refresh operations. These serializers integrate with Django REST Framework's validation system to process JWT authentication requests.

Capabilities

JWT Authentication Serializer

Validates username/password credentials and generates JWT tokens for successful authentication.

class JSONWebTokenSerializer(Serializer):
    # Dynamic fields based on user model
    # username_field: CharField (dynamically added based on User.USERNAME_FIELD)
    # password: PasswordField (write-only)
    
    def __init__(self, *args, **kwargs):
        """
        Dynamically adds username field based on User model configuration.
        
        Adds:
            - Username field (name from User.USERNAME_FIELD) 
            - Password field (write-only with password input type)
        """
    
    @property
    def username_field(self):
        """
        Returns the username field name from the User model.
        
        Returns:
            str: Field name used for username (e.g., 'username', 'email')
        """
    
    def validate(self, attrs):
        """
        Validates credentials and returns token with user data.
        
        Args:
            attrs (dict): Input data containing username and password
            
        Returns:
            dict: Contains 'token' (JWT string) and 'user' (User instance)
            
        Raises:
            ValidationError: For invalid credentials, inactive users, or missing fields
            
        Validation Process:
            1. Extracts username and password from input
            2. Authenticates user via Django's authenticate()
            3. Checks if user account is active
            4. Generates JWT payload and token
            5. Returns token and user data
        """

Base Verification Serializer

Abstract base class providing common token validation functionality for verification and refresh operations.

class VerificationBaseSerializer(Serializer):
    token = CharField()
    
    def validate(self, attrs):
        """
        Abstract validation method to be implemented by subclasses.
        
        Args:
            attrs (dict): Input data containing token
            
        Raises:
            NotImplementedError: Must be overridden by subclasses
        """
    
    def _check_payload(self, token):
        """
        Validates JWT token and returns decoded payload.
        
        Args:
            token (str): JWT token string
            
        Returns:
            dict: Decoded JWT payload
            
        Raises:
            ValidationError: For expired, malformed, or invalid tokens
            
        Validation includes:
            - Token signature verification
            - Expiration time checking
            - Payload structure validation
        """
    
    def _check_user(self, payload):
        """
        Validates user from JWT payload and returns User instance.
        
        Args:
            payload (dict): Decoded JWT payload
            
        Returns:
            User: Active user instance
            
        Raises:
            ValidationError: For missing users, inactive accounts, or invalid payloads
            
        Validation includes:
            - Username extraction from payload
            - User existence verification
            - User account status checking
        """

Token Verification Serializer

Validates JWT tokens and confirms their authenticity without generating new tokens.

class VerifyJSONWebTokenSerializer(VerificationBaseSerializer):
    def validate(self, attrs):
        """
        Verifies token validity and returns token with user data.
        
        Args:
            attrs (dict): Input data containing token to verify
            
        Returns:
            dict: Contains 'token' (original JWT) and 'user' (User instance)
            
        Raises:
            ValidationError: For invalid, expired, or malformed tokens
            
        Process:
            1. Validates token signature and expiration
            2. Extracts and validates user from payload
            3. Returns original token and user data
        """

Token Refresh Serializer

Validates existing tokens and generates new tokens with extended expiration times.

class RefreshJSONWebTokenSerializer(VerificationBaseSerializer):
    def validate(self, attrs):
        """
        Validates token and generates refreshed token with new expiration.
        
        Args:
            attrs (dict): Input data containing token to refresh
            
        Returns:
            dict: Contains 'token' (new JWT) and 'user' (User instance)
            
        Raises:
            ValidationError: For invalid tokens, expired refresh windows, or missing orig_iat
            
        Process:
            1. Validates existing token signature and structure
            2. Extracts and validates user from payload
            3. Checks original issued-at time (orig_iat) for refresh eligibility
            4. Verifies refresh hasn't exceeded maximum allowed time
            5. Generates new token with extended expiration
            6. Preserves original issued-at time in new token
            
        Requirements:
            - Token must contain 'orig_iat' field
            - Current time must be within refresh expiration window
            - JWT_ALLOW_REFRESH must be enabled in settings
        """

Usage Examples

Custom Authentication Serializer

from rest_framework_jwt.serializers import JSONWebTokenSerializer
from rest_framework import serializers
from django.contrib.auth import authenticate

class CustomJWTSerializer(JSONWebTokenSerializer):
    # Add extra fields
    remember_me = serializers.BooleanField(default=False)
    
    def validate(self, attrs):
        # Get standard validation result
        validated_data = super().validate(attrs)
        
        # Customize token expiration based on remember_me
        if attrs.get('remember_me'):
            user = validated_data['user']
            
            # Generate custom payload with longer expiration
            from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler
            from datetime import timedelta
            
            payload = jwt_payload_handler(user)
            payload['exp'] = payload['exp'] + timedelta(days=30)  # Extend expiration
            
            validated_data['token'] = jwt_encode_handler(payload)
        
        return validated_data

Custom Token Validation

from rest_framework_jwt.serializers import VerifyJSONWebTokenSerializer
from rest_framework import serializers

class CustomVerifySerializer(VerifyJSONWebTokenSerializer):
    def validate(self, attrs):
        # Standard validation
        validated_data = super().validate(attrs)
        
        # Add custom business logic
        user = validated_data['user']
        
        # Check additional user requirements
        if not user.profile.api_access_enabled:
            raise serializers.ValidationError("API access is disabled for this user")
        
        # Log token verification
        self.log_token_verification(user, attrs['token'])
        
        return validated_data
    
    def log_token_verification(self, user, token):
        # Custom logging logic
        import logging
        logger = logging.getLogger('jwt_auth')
        logger.info(f"Token verified for user {user.username}")

Manual Serializer Usage

from rest_framework_jwt.serializers import JSONWebTokenSerializer, RefreshJSONWebTokenSerializer

# Manual authentication
auth_serializer = JSONWebTokenSerializer(data={
    'username': 'testuser',
    'password': 'testpass123'
})

if auth_serializer.is_valid():
    token = auth_serializer.validated_data['token']
    user = auth_serializer.validated_data['user']
    print(f"Authentication successful for {user.username}")
else:
    print(f"Authentication failed: {auth_serializer.errors}")

# Manual token refresh
refresh_serializer = RefreshJSONWebTokenSerializer(data={
    'token': token
})

if refresh_serializer.is_valid():
    new_token = refresh_serializer.validated_data['token']
    print(f"Token refreshed successfully")
else:
    print(f"Token refresh failed: {refresh_serializer.errors}")

Integration with DRF Views

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_jwt.serializers import JSONWebTokenSerializer

class CustomAuthView(APIView):
    def post(self, request):
        serializer = JSONWebTokenSerializer(data=request.data)
        
        if serializer.is_valid():
            # Custom response formatting
            response_data = {
                'success': True,
                'token': serializer.validated_data['token'],
                'user': {
                    'id': serializer.validated_data['user'].id,
                    'username': serializer.validated_data['user'].username,
                },
                'message': 'Authentication successful'
            }
            return Response(response_data)
        else:
            return Response({
                'success': False,
                'errors': serializer.errors
            }, status=400)

Field Validation

Dynamic Username Field

The JSONWebTokenSerializer dynamically adds the username field based on your User model configuration:

# If User.USERNAME_FIELD = 'email'
# Serializer will have 'email' field instead of 'username'

# If User.USERNAME_FIELD = 'username'  
# Serializer will have 'username' field (default)

# Custom user model example
class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
    USERNAME_FIELD = 'email'  # Use email for authentication
    
# JSONWebTokenSerializer will automatically use 'email' field

Password Field

The password field is automatically configured with:

  • Write-only access (not included in serialized output)
  • Password input type for forms
  • Required validation

Error Handling

Serializers raise ValidationError for various conditions:

from rest_framework import serializers

# Authentication errors
{
    "non_field_errors": ["Unable to log in with provided credentials."]
}

# Field validation errors  
{
    "username": ["This field is required."],
    "password": ["This field is required."]
}

# User account errors
{
    "non_field_errors": ["User account is disabled."]
}

# Token validation errors
{
    "token": ["This field is required."]
}

# JWT-specific errors
{
    "non_field_errors": ["Signature has expired."]
}
{
    "non_field_errors": ["Error decoding signature."]
}

# Refresh-specific errors
{
    "non_field_errors": ["Refresh has expired."]
}
{
    "non_field_errors": ["orig_iat field is required."]
}

Configuration Dependencies

Serializers depend on various JWT settings:

  • JWT_PAYLOAD_HANDLER: Function to generate JWT payloads
  • JWT_ENCODE_HANDLER: Function to encode JWT tokens
  • JWT_DECODE_HANDLER: Function to decode JWT tokens
  • JWT_PAYLOAD_GET_USERNAME_HANDLER: Function to extract username from payload
  • JWT_ALLOW_REFRESH: Enable/disable token refresh functionality
  • JWT_REFRESH_EXPIRATION_DELTA: Maximum time allowed for token refresh

These settings control the behavior of token generation, validation, and refresh operations within the serializers.

Module Variables

The serializers module defines several handler function references and the User model:

User = get_user_model()
"""Reference to the configured Django User model."""

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
"""Function reference for generating JWT payloads from user instances."""

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
"""Function reference for encoding JWT tokens."""

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."""

Install with Tessl CLI

npx tessl i tessl/pypi-djangorestframework-jwt

docs

authentication.md

compatibility.md

configuration.md

index.md

jwt-utilities.md

serializers.md

views-endpoints.md

tile.json