Why SimpleJWT Over Session Auth for APIs
If you're building a React or Next.js frontend that talks to a Django backend, sessions don't work well across origins. JWT (JSON Web Token) authentication is the standard for decoupled frontends.
Installation
pip install djangorestframework-simplejwt
# settings.py
from datetime import timedelta
INSTALLED_APPS += ["rest_framework", "rest_framework_simplejwt"]
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
}
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=15),
"REFRESH_TOKEN_LIFETIME": timedelta(days=7),
"ROTATE_REFRESH_TOKENS": True,
"BLACKLIST_AFTER_ROTATION": True,
"AUTH_HEADER_TYPES": ("Bearer",),
}
URLs
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenBlacklistView,
)
urlpatterns = [
path("api/auth/token/", TokenObtainPairView.as_view()),
path("api/auth/token/refresh/", TokenRefreshView.as_view()),
path("api/auth/logout/", TokenBlacklistView.as_view()),
]
Custom Claims (Add User Data to Token)
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token["name"] = user.get_full_name()
token["role"] = user.profile.role
token["email"] = user.email
return token
Storing Tokens Securely on the Frontend
Never store JWTs in localStorage if you can avoid it - XSS can steal them. Use httpOnly cookies instead:
# Custom login view that sets cookie
class CookieTokenView(TokenObtainPairView):
def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
if response.status_code == 200:
response.set_cookie(
"access", response.data["access"],
httponly=True, secure=True, samesite="Lax",
max_age=15 * 60
)
return response
This is the exact setup I use for all my client portals.