Secure Your Django API with djangorestframework-simplejwt: A Complete Guide

Last updated 4 months ago | 335 views 75     5

Tags:- Python Django DRF

Introduction: Why Use JWT Authentication in Django?

APIs need security. That’s a fact.

When building RESTful APIs with Django Rest Framework (DRF), securing endpoints is crucial. You don't want unauthorized users accessing user data, posting content, or deleting resources.

By default, DRF provides several authentication schemes—but JSON Web Tokens (JWT) offer a modern, stateless, and scalable alternative.

That’s where djangorestframework-simplejwt comes in.

This package makes integrating JWTs into your Django project painless, giving you access tokens, refresh tokens, and token-based security—all without the hassle.


Step-by-Step: Setting Up djangorestframework-simplejwt

✅ Step 1: Install the Package

Install Simple JWT via pip:

pip install djangorestframework-simplejwt

✅ Step 2: Update Your Django Settings

# settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
]

# Configure REST framework to use JWT authentication
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

✅ Step 3: Set Up URL Endpoints for Token Management

# urls.py

from django.urls import path
from rest_framework_simplejwt.views import (
    TokenObtainPairView,  # For login (access + refresh tokens)
    TokenRefreshView,     # To get a new access token
    TokenVerifyView       # Optional: verify token validity
)

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]

✅ Step 4: Protect Your Views with Authentication

# views.py

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

class ProtectedView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({'message': 'This is a protected endpoint!'})

Now, this view can only be accessed with a valid JWT access token.


Full Working Example

Here’s everything put together.

settings.py

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

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

urls.py

from django.urls import path
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView
)
from .views import ProtectedView

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('api/protected/', ProtectedView.as_view(), name='protected'),
]

views.py

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

class ProtectedView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"message": "Hello, authenticated user!"})

Testing the Flow (Using Postman or Curl)

  1. Login to Get Tokens
    POST /api/token/ with username and password
    Returns: access + refresh tokens

  2. Access Protected Route
    GET /api/protected/
    Header: Authorization: Bearer <access_token>

  3. Refresh the Access Token
    POST /api/token/refresh/ with refresh token


Token Overview

Token Type Purpose Expiration (Default)
Access Token Used to authenticate most requests 5 minutes
Refresh Token Used to get new access tokens 1 day

Customize token lifetimes in settings.py:

from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
}

⚠️ Tips & Common Pitfalls

✅ Tips

  • Use TokenObtainPairView for login, not TokenObtainView.

  • Refresh tokens should be securely stored on the client (e.g., HttpOnly cookies).

  • Always add IsAuthenticated to your protected views.

❌ Common Pitfalls

  • Forgetting to set JWTAuthentication in DEFAULT_AUTHENTICATION_CLASSES

  • Missing the "Bearer " prefix in the Authorization header

  • Using expired or invalid tokens without proper error handling


Comparison: JWT vs Session Auth in Django

Feature Session Authentication JWT Authentication (SimpleJWT)
Storage Server-side Client-side (token in browser)
Scalability Limited (server memory) Scales better (stateless)
Use in Mobile/SPA Limited Ideal
Security Risk Session hijacking Token leakage

✅ Summary & Best Practices

Using djangorestframework-simplejwt is a modern, efficient way to secure your Django API using JWT authentication. It's simple to integrate, stateless by nature, and works well for SPAs, mobile apps, and microservices.

Best Practices

  • Keep token lifetimes short (e.g., 5–15 minutes)

  • Use refresh tokens only on secure channels

  • Protect sensitive endpoints with IsAuthenticated

  • Consider token blacklisting if needed (TokenBlacklist app)

  • Rotate tokens when users change passwords or log out


Bonus: Need More?

Explore these extensions and customizations:

  • Custom token claims (MyTokenObtainPairView)

  • JWT with social login

  • JWT and cookie-based auth combo

  • Blacklisting and logout via rest_framework_simplejwt.token_blacklist