DevDuniya
Mar 26, 2025
In this comprehensive guide, we'll build a Django REST API with JWT (JSON Web Token) authentication, covering user registration, login, and a protected dashboard. JWT authentication is widely used in modern web and mobile applications because of its stateless nature and security benefits.
By the end of this tutorial, you'll have a fully functional Django REST API that:
โ
Allows users to register and login using JWT tokens
โ
Secures API endpoints with token-based authentication
โ
Provides a protected dashboard for authenticated users
JWT (JSON Web Token) authentication is a popular, secure, and scalable way to handle API authentication. Hereโs why you should use it:
๐น Stateless: No need to store tokens on the server (unlike session-based auth).
๐น Secure: Tokens are digitally signed and can include expiration.
๐น Scalable: Works well with microservices and mobile apps.
๐น Flexible: Can be used across different platforms (web, mobile, IoT).
Django REST Framework (DRF) with SimpleJWT makes JWT implementation seamless.
Before we start, ensure you have:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install django djangorestframework djangorestframework-simplejwt
django-admin startproject jwt_auth_project
cd jwt_auth_project
python manage.py startapp accounts
settings.py
for JWT AuthenticationAdd the following to jwt_auth_project/settings.py
:
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework_simplejwt',
'accounts',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
# JWT Settings
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
}
python manage.py migrate
python manage.py createsuperuser # For admin access
In accounts/models.py
:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
def __str__(self):
return self.username
Update settings.py
to use the custom model:
AUTH_USER_MODEL = 'accounts.CustomUser'
Run migrations:
python manage.py makemigrations
python manage.py migrate
In accounts/serializers.py
:
from rest_framework import serializers
from django.contrib.auth import get_user_model
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
User = get_user_model()
class UserRegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ['username', 'email', 'password']
def create(self, validated_data):
user = User.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['password']
)
return user
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token['username'] = user.username
return token
In accounts/views.py
:
from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenObtainPairView
from .serializers import UserRegisterSerializer, MyTokenObtainPairSerializer
class RegisterView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = UserRegisterSerializer
class LoginView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
class DashboardView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
user = request.user
data = {
"message": f"Welcome, {user.username}!",
"email": user.email,
"last_login": user.last_login
}
return Response(data)
jwt_auth_project/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import TokenRefreshView
from accounts.views import RegisterView, LoginView, DashboardView
urlpatterns = [
path('admin/', admin.site.urls),
path('api/register/', RegisterView.as_view(), name='register'),
path('api/login/', LoginView.as_view(), name='login'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/dashboard/', DashboardView.as_view(), name='dashboard'),
]
python manage.py runserver
Endpoint: http://127.0.0.1:8000/api/register/
Request Body (JSON):
{
"username": "testuser",
"email": "test@example.com",
"password": "securepassword123"
}
Endpoint: http://127.0.0.1:8000/api/login/
Response:
{
"refresh": "xxxxx.yyyyy.zzzzz",
"access": "aaaaa.bbbbb.ccccc"
}
Headers:
{
"Authorization": "Bearer aaaaa.bbbbb.ccccc"
}
Response:
{
"message": "Welcome, testuser!",
"email": "test@example.com",
"last_login": "2023-10-01T12:00:00Z"
}
Weโve successfully built a Django REST API with JWT authentication, including:
โ
User registration
โ
JWT-based login
โ
Token refresh
โ
Protected dashboard endpoint
This setup is production-ready and can be extended with:
๐น Password reset functionality
๐น Email verification
๐น Social authentication (Google, Facebook, etc.)
By using Django REST Framework and SimpleJWT, weโve ensured security, scalability, and ease of integration with frontend frameworks like React, Vue, or Angular.