Building a Custom Authentication Class in Django Rest Framework (DRF)

Custom authentication methods are essential for tailoring security to specific application needs. This article guides you through creating a custom authentication class in DRF, leveraging tokens to authenticate requests.
Understanding the Components
Custom Authentication Exceptions
The AuthenticationFailed
exception provides a standardized way to signal failed authentication, including a customizable status code and error message.
from rest_framework.exceptions import APIException
from rest_framework import status
class AuthenticationFailed(APIException):
status_code = status.HTTP_401_UNAUTHORIZED
default_code = "authentication_failed"
Defining a User Proxy Class
The ResourceUser
class extends AnonymousUser
to include additional logic for authentication.
from django.contrib.auth.models import AnonymousUser
class ResourceUser(AnonymousUser):
def __init__(self, resource):
self.resource = resource
@property
def is_authenticated(self):
return self.resource.is_valid()
This class links a Resource
object to the user and checks if it is valid.
Token-Based Authentication
The TokenAuthentication
class retrieves and validates tokens from the Authorization
header.
from rest_framework.authentication import BaseAuthentication
class TokenAuthentication(BaseAuthentication):
"""
Authenticate using a token from the `Authorization` header.
"""
def authenticate(self, request):
auth_header = request.headers.get("Authorization")
if not auth_header:
return None
token_str = (
auth_header.split("Bearer ")[-1]
if "Bearer " in auth_header
else auth_header
)
try:
token = Token.objects.get(token=token_str)
if token.is_valid():
return (ResourceUser(token.resource), token)
raise AuthenticationFailed("Invalid request.")
except Token.DoesNotExist:
raise AuthenticationFailed("Invalid token.")
Key Considerations
- Security Best Practices
Ensure tokens are securely generated, stored, and expire after a reasonable period. - Error Handling
Provide meaningful error messages and handle exceptions gracefully. - Integration with Views
Demonstrate how to apply the custom authentication class to DRF views.
Example Usage
Here’s how to secure a view with the TokenAuthentication
class:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class SecureView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({"message": "Authenticated request!"})
Modifying the Settings File
To use the TokenAuthentication
class across your DRF views, you need to tell Django to use it by default. This is done by adding the class to the DEFAULT_AUTHENTICATION_CLASSES
setting in your settings.py
file.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'{yourapp}.authentication.TokenAuthentication',
],
# Other settings can be added here, e.g., permissions, pagination, etc.
}
Conclusion
Custom authentication provides flexibility for implementing domain-specific security requirements in your DRF applications. By following the example above, you can create a robust token-based authentication system tailored to your needs.