Django includes a complete authentication system: user models, sessions, login/logout views, and password hashing. You get it all without installing anything extra.
TL;DR: Implement user authentication in Django using the built-in auth system and JWT tokens for DRF.
Stack: Python, Django, djangorestframework-jwt
Level: Beginner
Reading time: ~7 min
Install
Django==3.0.8
djangorestframework==3.14.0
djangorestframework-jwt==1.11.0
Configure JWT in settings.py
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER': 'api.utils.jwt_response_payload_handler',
}
Add login route to urls.py
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
path('admin/', admin.site.urls),
path('login', obtain_jwt_token),
]
Create serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
username = serializers.CharField()
password = serializers.CharField()
email = serializers.CharField()
class Meta:
model = User
fields = ('id', 'username', 'password', 'email')
Create utils.py (custom JWT payload)
from .serializers import UserSerializer
def jwt_response_payload_handler(token, user=None, request=None):
user_data = UserSerializer(user, context={'request': request}).data
return {
'token': token,
'userid': user_data['id'],
'username': user_data['username'],
}
Create a user endpoint
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
@api_view(['POST'])
def create_user(request):
username = request.data.get('username')
email = request.data.get('email')
password = request.data.get('password')
if not username or not email or not password:
return Response({'error': 'Missing fields'}, status=status.HTTP_400_BAD_REQUEST)
if User.objects.filter(username=username).exists() or User.objects.filter(email=email).exists():
return Response({'error': 'Username or email already exists'}, status=status.HTTP_400_BAD_REQUEST)
user = User(username=username, email=email, password=make_password(password))
user.save()
return Response({'success': 'User created successfully'}, status=status.HTTP_201_CREATED)
What you’ve built
Django JWT authentication working end-to-end: a login endpoint that returns a token, a custom payload with user info, and a user creation endpoint.
Next steps
- Add AUTHENTICATION_BACKENDS to support login via email instead of username, which most users expect.
- Use Django AllAuth for social authentication (Google, GitHub) when you need OAuth login without building it from scratch.
- Extend the default User model with a OneToOneField profile to add user-specific data without modifying the auth model.
Questions or feedback? Find me on LinkedIn or GitHub.