DEV Community

Cover image for How to Build a Task Manager API with Django REST Framework: Part 3 - Authentication and Permission
kihuni
kihuni

Posted on

How to Build a Task Manager API with Django REST Framework: Part 3 - Authentication and Permission

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

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
]
Enter fullscreen mode Exit fullscreen mode

Then, run migrations to apply the necessary database changes:

python manage.py migrate

Enter fullscreen mode Exit fullscreen mode

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
    ),
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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'),
]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

register user
Copy the token!

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
}
Enter fullscreen mode Exit fullscreen mode

Click Send. Expect the same token:

login

Add a Task

  • New request: POST to http://127.0.0.1:8000/api/tasks/.
  • In Headers, add:
    Key: Authorization
    Value: Token c80425f150f99e72553d43cfac2aaa113491de5d(use your token)

  • In Body (raw JSON):

{
    "title": "Myblog",
    "description": "My first task",
    "completed": false
}
Enter fullscreen mode Exit fullscreen mode

Send it! You’ll see the task with an ID and timestamp.

addtask

Access Tasks

New request: Method GET, URL http://127.0.0.1:8000/api/tasks/.

  • Headers tab:add:
    Key: Authorization
    Value: Token c80425f150f99e72553d43cfac2aaa113491de5d(use your token)

  • Click Send.

  • Expected: 200 OK, or your task list.

tasks

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)