Introduction
Welcome back to our Django REST Framework (DRF) adventure! In Part 1, we set up our Django project, installed DRF, and built the Task model. In Part 2, we implemented API endpoints for CRUD operations, allowing us to create, read, update, and delete tasks.
In Part 3, we’ll add authentication and permissions to our Task Manager API. This will ensure that only authenticated users can access and modify tasks. By the end of this guide, you’ll have a secure API where users can register, log in, and perform operations based on their permissions.
Let’s dive in! 🚀
Table of Contents
- Step 1: Set Up Django Authentication
- Step 2: Add DRF Token Authentication
- Step 3: Build Registration and Login Endpoints
- Step 4: Secure Your Task Endpoints
- Step 5: Test Your Secure API
- Conclusion
- What’s Next?
Step 1: Set Up Django Authentication
Django’s got a built-in authentication system that’s perfect for managing users. Let’s make sure it’s ready to roll.
In taskmanager/settings.py
, check that these apps are in INSTALLED_APPS
:
INSTALLED_APPS = [
...
'django.contrib.auth', # User management
'django.contrib.contenttypes', # Required for auth
'rest_framework', # DRF core
'rest_framework.authtoken', # Token auth support
'tasks', # Our app
]
Then, run migrations to apply the necessary database changes:
python manage.py migrate
What’s this doing?
This sets up Django’s user tables (like auth_user) so we can handle logins and permissions. No extra work is needed—Django’s got your back!
Step 2: Add DRF Token Authentication
We’ll use Token Authentication from DRF, where each user gets a unique token to prove who they are. Update taskmanager/settings.py with:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated', # Only logged-in users allowed
),
}
What’s happening?
-
TokenAuthentication
: Users send a token with requests to authenticate. -
IsAuthenticated
: Locks down all endpoints unless a valid token is provided.
To auto-generate tokens when users sign up, create tasks/signals.py:
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
Then, link it in tasks/apps.py:
from django.apps import AppConfig
class TasksConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'tasks'
def ready(self):
import tasks.signals # Connect the signal
Step 3: Build Registration and Login Endpoints
Let’s give users a way to join the party (register) and get in (log in).
Create a User Serializer
In tasks/serializers.py, add:
from django.contrib.auth.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=True)
class Meta:
model = User
fields = ['username', 'password']
def create(self, validated_data):
user = User.objects.create_user(**validated_data) # Securely hashes password
return user
Add Registration and Login Views
Update tasks/views.py:
from django.contrib.auth import authenticate
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.permissions import AllowAny
from .serializers import UserSerializer
class RegisterView(APIView):
permission_classes = [AllowAny] # Anyone can register
def post(self, request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginView(APIView):
permission_classes = [AllowAny] # Anyone can log in
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user:
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key}, status=status.HTTP_200_OK)
return Response({'error': 'Invalid Credentials'}, status=status.HTTP_400_BAD_REQUEST)
Hook Up the URLs
In tasks/urls.py, add these routes:
from django.urls import path
from .views import RegisterView, LoginView, TaskListCreateView, TaskDetailView
urlpatterns = [
path('register/', RegisterView.as_view(), name='register'),
path('login/', LoginView.as_view(), name='login'),
path('tasks/', TaskListCreateView.as_view(), name='task-list-create'),
path('tasks/<int:pk>/', TaskDetailView.as_view(), name='task-detail'),
]
What’s this doing?
- Register: Creates a user and returns a token.
- Login: Checks credentials and hands out a token if they match.
Step 4: Secure Your Task Endpoints
Modify your TaskListCreateView
and TaskDetailView
to restrict access to authenticated users only.
Update tasks/views.py
:
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from .models import Task
from .serializers import TaskSerializer
class TaskListCreateView(generics.ListCreateAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
permission_classes = [IsAuthenticated]
class TaskDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
permission_classes = [IsAuthenticated]
Why this matters:
The IsAuthenticated
permission ensures users must send a valid token with every request—keeping your API safe from prying eyes.
Step 5: Test Your Secure API
Start your server:
python manage.py runserver
We’ll use Postman to test. If you haven't already, download it from postman.com. It’s a free, user-friendly tool for API testing.
- Open Postman and create a new request.
- Set the method to POST and the URL to
http://127.0.0.1:8000/api/register/
. - Go to the Body tab, select raw, and choose JSON from the dropdown.
Register a User
{
"username" : "kihuni",
"password" : 1234
}
Log In a User
- Create a new request.
- Set method to POST and URL to
http://127.0.0.1:8000/api/login/
. - In the Body tab, use raw JSON:
{
"username" : "kihuni",
"password" : 1234
}
Click Send. Expect the same token:
Add a Task
- New request:
POST to http://127.0.0.1:8000/api/tasks/
. In Headers, add:
Key:Authorization
Value: Tokenc80425f150f99e72553d43cfac2aaa113491de5d
(use your token)In Body (raw JSON):
{
"title": "Myblog",
"description": "My first task",
"completed": false
}
Send it! You’ll see the task with an ID and timestamp.
Access Tasks
New request: Method GET, URL http://127.0.0.1:8000/api/tasks/
.
Headers tab:add:
Key: Authorization
Value: Tokenc80425f150f99e72553d43cfac2aaa113491de5d
(use your token)Click Send.
Conclusion
You’ve successfully added authentication and secured your Task Manager API. Now, only registered and authenticated users can access the API.
Summary Checklist
- ✅Set up Django’s auth and Task model migrations
- ✅Added DRF Token Authentication
- ✅Built open registration/login endpoints
- ✅Secured task endpoints
- ✅Tested with Postman
What’s Next?
In Part 4, we’ll explore how to add user-specific tasks so that each user can only manage their tasks. Stay tuned🚀
Top comments (0)