Authentication

Django REST Framework (DRF) provides a robust and flexible authentication system to secure your API. Here’s an overview of everything you need to know about authentication in DRF:

Built-in Authentication Classes

DRF comes with several built-in authentication classes:

  • BasicAuthentication: Uses HTTP Basic Authentication. It’s simple but not very secure as it sends credentials in plain text.
  • SessionAuthentication: Uses Django’s session framework. It’s suitable for browser-based clients that have a CSRF token.
  • TokenAuthentication: Uses token-based authentication. A token is provided to the client after the initial login, which must be included in the Authorization header of subsequent requests.
  • RemoteUserAuthentication: Useful for integrating with existing authentication frameworks that rely on the REMOTE_USER environment variable.
  • Custom Authentication: You can create custom authentication classes by subclassing BaseAuthentication.

Configure Settings

# settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',  # Use session authentication
        'rest_framework.authentication.TokenAuthentication',    # Use token authentication
        # Add other authentication classes as needed
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',  # Ensure authenticated users have access
    ],
}

Implement Authentication

Session Authentication

For session authentication, ensure you have ‘rest_framework.authentication.SessionAuthentication’ in your DEFAULT_AUTHENTICATION_CLASSES. This relies on Django’s session framework and requires users to log in via the web interface or obtain a session cookie through a login view.

Token Authentication

For token authentication:

  • Generate Tokens: Use Django’s Token model to generate tokens for users. You can create tokens manually via Django admin or automatically when a user is created.

  • Include Token in Requests: Clients must include the token in the Authorization header of API requests:

Install the package

pip install djangorestframework
pip install djangorestframework-simplejwt

Add rest_framework and rest_framework.authtoken to your INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',
]

Run migrations to create the token model

python manage.py migrate

Create a view to generate tokens

from rest_framework.authtoken.views import obtain_auth_token
from django.urls import path

urlpatterns = [
    path('api-token-auth/', obtain_auth_token, name='api_token_auth'),
]

Use tokens in your API requests

Authorization: Token <your_token_key>

DRF provides a built-in view (ObtainAuthToken) to obtain tokens via POST requests to /api/token/.

Custom Authentication

You can implement custom authentication by subclassing BaseAuthentication and overriding the authenticate method.

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class CustomAuthentication(BaseAuthentication):
    def authenticate(self, request):
        auth = request.headers.get('Authorization')
        if not auth:
            return None
        if auth != 'expected_token':
            raise AuthenticationFailed('Invalid token')
        return (None, None)  # Return a tuple of (user, auth)

Permission Classes

In addition to authentication, you need to handle permissions. DRF provides several built-in permission classes like IsAuthenticated, IsAdminUser, and IsAuthenticatedOrReadOnly. You can also create custom permission classes by subclassing BasePermission.

from rest_framework.permissions import BasePermission

class IsOwner(BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj.owner == request.user

Using Authentication and Permissions Together

You typically use both authentication and permissions in your views or viewsets.

from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated

class MyView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({'message': 'Hello, world!'})

Set Up Views and Permissions

Views

Define views using DRF’s APIView, ViewSet, or @api_view decorator, and apply authentication requirements:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated

class ExampleView(APIView):
    permission_classes = [IsAuthenticated]  # Requires authenticated access

    def get(self, request):
        content = {'message': 'Hello, World!'}
        return Response(content)
Back to top