Secure Your Django API with djangorestframework-simplejwt: A Complete Guide
Last updated 4 months ago | 335 views 75 5

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)
-
Login to Get Tokens
POST /api/token/
with username and password
Returns: access + refresh tokens -
Access Protected Route
GET /api/protected/
Header:Authorization: Bearer <access_token>
-
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, notTokenObtainView
. -
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
inDEFAULT_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