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:
Author

Benedict Thekkel

📘 Authentication in Django REST Framework (DRF)

🔐 Authentication = Who are you?
🔓 Authorization = Are you allowed to do this?

DRF handles authentication via pluggable classes set in REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'].


🧱 Built-in Authentication Classes in DRF

Class Description Use Case
SessionAuthentication Uses Django’s session & CSRF cookies Browser-based apps (Django templates)
BasicAuthentication Base64 username/password in header Quick testing, not secure for production
TokenAuthentication Token in Authorization: Token <token> Mobile apps, SPAs, API clients
JWTAuthentication (via 3rd-party) Token with expiry, stateless Modern API design
RemoteUserAuthentication Uses REMOTE_USER env var Enterprise intranet SSO
CustomAuthentication Your own class Advanced integrations (mTLS, API keys, etc.)

🛠 Basic Setup

In settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ]
}

This enables both browser and API clients to authenticate.


✅ Common Auth Workflows

Type User Experience Use With
SessionAuth Log in through Django Admin or LoginView Browsers
TokenAuth POST username+password → get token Postman, scripts, apps
JWTAuth POST credentials → get access/refresh tokens SPAs, mobile apps
API Keys Header with a static token 3rd-party integrations
OAuth2 / SSO Login via Google, GitHub, etc. SaaS, enterprise

🔑 Token Authentication (Built-in)

  1. Add 'rest_framework.authtoken' to INSTALLED_APPS
  2. Run python manage.py migrate
  3. Add login view:
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    path('api/token/', obtain_auth_token),
]
  1. Use it:
POST /api/token/
{ "username": "user", "password": "pass" }

# Response:
{ "token": "abc123" }

# Then use:
Authorization: Token abc123

🧠 Custom Authentication

Make a custom class if you want to: - Use X-API-Key headers - Authenticate based on certificate (mTLS) - Add throttling per user type

Example:

from rest_framework.authentication import BaseAuthentication

class CustomTokenAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.headers.get('X-Api-Key')
        if token == "expected_token":
            return (MyUserObject, None)
        return None

🔐 Login via Session + CSRF (For Browsers)

  • Requires logging in via Django LoginView or Admin
  • Automatically sends sessionid cookie
  • Must include CSRF token in all modifying requests

Good for: - Internal admin views - API browsable interface (/api/ with DRF)


🔒 Permissions (AuthZ, not AuthN)

Once the user is authenticated, permissions check whether they can do something:

Class Description
AllowAny Open to everyone
IsAuthenticated Only logged-in users
IsAdminUser Only superusers
IsAuthenticatedOrReadOnly Anyone can read, only authed can write
Custom has_permission(self, request, view) logic

Used in your views like:

class MyViewSet(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]

🔁 Session vs Token vs JWT (Comparison)

Feature SessionAuth TokenAuth JWT
Cookie-based? ✅ Yes ❌ No ❌ No
Header-based? ❌ No ✅ Yes ✅ Yes
Expiry Support Manual Manual ✅ Built-in
Stateless? ❌ No ✅ Yes ✅ Yes
Best For Web apps Simple API clients Production-grade APIs

🔐 Example: Login with JWT and Use API

# Login
curl -X POST /api/token/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "pass"}'

# Response:
{
  "access": "ey...",
  "refresh": "ey..."
}

# Use it
curl -H "Authorization: Bearer ey..." /api/clients/

🔄 Refresh Tokens (JWT)

When access token expires, use refresh:

POST /api/token/refresh/
{
  "refresh": "ey..."
}

Get a new access token without re-logging in.


🔐 Advanced Use Cases

Feature Use
API key for 3rd parties Custom auth class, or use drf-api-key
Service accounts Create special users, assign static tokens
mTLS authentication Terminate TLS at Nginx/LB, forward identity headers
OAuth2 Use django-allauth, django-oauth-toolkit

🧠 Diagram: DRF Auth Flow (JWT)

[Client]
  |
  | -- POST /api/token/  -->  [DRF Login View]
  | <-- {access, refresh}
  |
  | -- GET /api/data/  (Authorization: Bearer <access>)
  | --> DRF checks JWT -> decodes -> authenticates user

✅ Summary Cheat Sheet

Concept You Should Know
DRF supports multiple auth systems ✅ Use DEFAULT_AUTHENTICATION_CLASSES
Token vs JWT JWT is stateless + has expiry
SessionAuth Great for browser use, requires CSRF
JWTAuth Best for API use (SPAs, mobile)
Permissions are separate from auth Use permission_classes

Back to top