Paramclasses Academy - Blog

Tutorials Details

←
Post 24 of 29
→

Django REST Framework Authentication and Permissions: Token Authentication, User Access Control, and Securing REST APIs

Django REST Framework Authentication and Permissions: Token Authentication, User Access Control, and Securing REST APIs

October 21, 2026

Introduction

Authentication and Permissions in Django REST Framework (DRF) help protect REST APIs from unauthorized access. Authentication identifies the user making a request, while permissions determine whether that user is allowed to perform a particular operation.

For example, a Student Management API may allow anyone to view public course information while restricting student creation, modification, and deletion to authorized users.

Django REST Framework supports several authentication approaches, including Session Authentication, Basic Authentication, and Token Authentication. It also provides permission classes such as AllowAny, IsAuthenticated, IsAdminUser, and IsAuthenticatedOrReadOnly.

In this module, you will learn how to authenticate users, configure permissions, create authentication tokens, and protect API endpoints.

What You Will Learn

  • What authentication and permissions mean.

  • The difference between authentication and authorization.

  • Common authentication methods in DRF.

  • How to configure authentication classes.

  • How to use built-in permission classes.

  • How to enable Token Authentication.

  • How to obtain and use authentication tokens.

  • How to protect ViewSets and API endpoints.

  • How to restrict access to authorized users.

  • How to test authenticated and unauthenticated requests.

1. Understanding Authentication and Authorization

Authentication verifies the identity of a user or client making an API request.

Authorization determines what the authenticated user is allowed to access or do.

For example, imagine a Student Management System:

  • A visitor can access public course information.

  • A logged-in student can access permitted student services.

  • An administrator can manage student records if the configured permissions allow it.

Authentication and authorization work together to protect application data.

Authentication vs Permissions

Feature Authentication Permissions
Purpose Identifies the requester Determines whether access is allowed
Main question Who is making the request? What can this requester do?
Example Validating a token Allowing only administrators to delete records
DRF configuration authentication_classes permission_classes

Important: Authentication alone does not automatically give a user permission to access every record.

2. Common Authentication Methods in DRF

Django REST Framework supports multiple authentication methods.

Session Authentication

Session Authentication uses Django's session framework. It is useful for APIs accessed through a browser where users log in through Django's authentication system.

It is commonly used with browser-based applications and may require CSRF protection for unsafe requests.

Basic Authentication

Basic Authentication sends a username and password through the HTTP Authorization header, encoded using Base64.

Base64 is not encryption. Basic Authentication should only be used over HTTPS, and credentials must be handled securely.

Token Authentication

Token Authentication allows a client to send a token instead of submitting a username and password with every request.

The client typically sends the token in the HTTP Authorization header.

Example:

Authorization: Token YOUR_AUTH_TOKEN

The token must be kept private and should never be exposed in public code or logs.

Choosing an Authentication Method

Method Common Use
Session Authentication Browser-based applications
Basic Authentication Simple testing and controlled environments over HTTPS
Token Authentication APIs using DRF's built-in token system
JWT Authentication APIs that need JSON Web Tokens through an additional package

Note: JWT authentication is not included automatically in Django REST Framework's core package. It normally requires a separate library.

3. Installing Django REST Framework

If Django REST Framework is not installed in your project, run:

pip install djangorestframework

Add the required applications to settings.py:

INSTALLED_APPS = [
    # Existing Django applications
    "rest_framework",
]

For the built-in Token Authentication system, also add:

INSTALLED_APPS = [
    # Existing Django applications
    "rest_framework",
    "rest_framework.authtoken",
]

If these applications are already configured, do not add duplicate entries.

Run the database migrations:

python manage.py migrate

This creates the database tables required by the token authentication system.

4. Configuring Global Authentication and Permissions

Open your project's settings.py.

Add or update the REST_FRAMEWORK configuration:

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.TokenAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
}

Explanation:

  • DEFAULT_AUTHENTICATION_CLASSES defines the authentication methods used by default.

  • SessionAuthentication supports Django sessions.

  • TokenAuthentication supports DRF's built-in token system.

  • DEFAULT_PERMISSION_CLASSES determines the default access policy for API views.

With this configuration, API views use IsAuthenticated by default unless their permissions are overridden.

Important: If you configure IsAuthenticated globally, anonymous users will not be able to access API endpoints that do not explicitly override the permission policy.

5. Understanding Built-in Permission Classes

DRF provides several useful permission classes.

Permission Purpose
AllowAny Allows any requester, including unauthenticated users
IsAuthenticated Requires an authenticated user
IsAdminUser Allows users whose Django is_staff flag is true
IsAuthenticatedOrReadOnly Allows read-only requests to everyone and unsafe requests only to authenticated users

AllowAny

Use AllowAny when an endpoint should be publicly accessible.

from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response


class PublicCourseView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        return Response({
            "message": "This is public course information."
        })

IsAuthenticated

Use IsAuthenticated when a user must log in before accessing the endpoint.

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response


class PrivateDashboardView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({
            "message": "Welcome to your private dashboard."
        })

IsAdminUser

Use IsAdminUser when access should be limited to users with Django's is_staff=True flag.

from rest_framework.permissions import IsAdminUser
from rest_framework.views import APIView
from rest_framework.response import Response


class AdminDashboardView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        return Response({
            "message": "Welcome to the admin dashboard."
        })

Important: IsAdminUser checks the Django is_staff flag. It does not simply check whether a user's username is admin.

6. Creating a Token for a User

With DRF's built-in Token Authentication, each user can have an associated authentication token.

You can create a token using Django's management shell.

Run:

python manage.py shell

Then execute:

from django.contrib.auth import get_user_model
from rest_framework.authtoken.models import Token

User = get_user_model()

user = User.objects.get(username="admin")
token, created = Token.objects.get_or_create(user=user)

print(token.key)

Replace "admin" with the username of an existing user.

Explanation:

  • get_user_model() retrieves the project's configured user model.

  • Token.objects.get_or_create() retrieves the existing token or creates one.

  • token.key contains the token value.

Keep the token private. Anyone who obtains a valid token may be able to act as the associated user within that user's permitted access.

7. Creating a Token Authentication Endpoint

DRF provides a built-in view for obtaining authentication tokens.

Open your project's main urls.py and add the following route:

from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/", include("students.urls")),
    path("api/token/", obtain_auth_token, name="api_token"),
]

Make sure the students app and URL configuration match your project.

The token endpoint is now available at:

http://127.0.0.1:8000/api/token/

Send a POST request with a valid username and password:

{
    "username": "admin",
    "password": "your_password"
}

A successful response looks like this:

{
    "token": "your_generated_token"
}

The returned token is an example format. Your actual token will be generated by your application.

Security note: Use HTTPS in production and never publish real credentials or tokens in screenshots, source control, or tutorial examples.

8. Using a Token to Access a Protected API

After obtaining a token, include it in the Authorization header of your request.

Example:

GET /api/students/
Authorization: Token YOUR_AUTH_TOKEN

Using curl:

curl -H "Authorization: Token YOUR_AUTH_TOKEN" http://127.0.0.1:8000/api/students/

Replace YOUR_AUTH_TOKEN with the actual token.

If the token is valid and the user has permission to access the endpoint, DRF returns the requested data.

If the request has no valid authentication and the endpoint requires an authenticated user, access is denied.

Remember: The exact response status can depend on the configured authentication classes and permissions.

9. Protecting a ModelViewSet

Suppose you created a StudentViewSet using ModelViewSet in the previous module.

You can protect it by adding IsAuthenticated:

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from .models import Student
from .serializers import StudentSerializer


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer
    permission_classes = [IsAuthenticated]

Now every standard action in this ViewSet requires authentication.

These include:

  • Listing students.

  • Retrieving a student.

  • Creating a student.

  • Updating a student.

  • Deleting a student.

Important: This example requires authentication but does not automatically restrict users to their own student records. For private or sensitive data, also implement appropriate queryset filtering and object-level permissions.

10. Allowing Public Reads but Restricting Changes

Sometimes an API should allow everyone to read data while requiring authentication for changes.

Use IsAuthenticatedOrReadOnly:

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from .models import Student
from .serializers import StudentSerializer


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]

With this permission:

  • Anonymous users can use safe methods such as GET.

  • Authenticated users may perform unsafe methods if other permission checks allow them.

  • POST, PUT, PATCH, and DELETE are not allowed for anonymous users.

Important: This permission does not restrict write operations to administrators. If only administrators should change records, use a stricter permission policy.

11. Creating an Admin-Only Permission

If only staff users should modify student records, you can create a custom permission.

Create students/permissions.py:

from rest_framework.permissions import BasePermission, SAFE_METHODS


class IsStaffOrReadOnly(BasePermission):
    def has_permission(self, request, view):
        if request.method in SAFE_METHODS:
            return True

        return (
            request.user
            and request.user.is_authenticated
            and request.user.is_staff
        )

Use the permission in your ViewSet:

from rest_framework import viewsets
from .models import Student
from .serializers import StudentSerializer
from .permissions import IsStaffOrReadOnly


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer
    permission_classes = [IsStaffOrReadOnly]

How it works:

  • SAFE_METHODS contains GET, HEAD, and OPTIONS.

  • Safe requests are allowed by this permission.

  • Write requests require an authenticated user with is_staff=True.

This is a simple example of role-related access control.

Production consideration: If student information is private, allowing every visitor to read every student record may be inappropriate. Combine permissions with appropriate queryset filtering.

12. Understanding Request.user and Request.auth

After successful authentication, DRF exposes authentication information through the request.

request.user

Represents the authenticated user. For an unauthenticated request, it generally represents an anonymous user.

request.auth

Contains additional authentication information when provided by the authentication mechanism. With DRF Token Authentication, it normally contains the authenticated token object.

Example:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated


class CurrentUserView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({
            "username": request.user.get_username(),
            "is_staff": request.user.is_staff,
        })

This endpoint returns basic information about the authenticated user.

Do not expose passwords, secret tokens, or other sensitive authentication information in API responses.

13. Token Authentication Security Best Practices

Authentication must be implemented carefully, particularly for production applications.

Follow these practices:

  1. Use HTTPS for all production API traffic.

  2. Keep authentication tokens confidential.

  3. Never commit tokens or passwords to Git.

  4. Apply appropriate permissions to every protected endpoint.

  5. Filter querysets to prevent unauthorized access to private records.

  6. Use strong passwords and secure account-management practices.

  7. Rotate or revoke tokens when they may have been compromised.

  8. Avoid logging Authorization headers.

  9. Use rate limiting or throttling where appropriate.

  10. Review whether the built-in token system meets your application's security requirements.

Token limitation: DRF's built-in token authentication uses a relatively simple token model. It does not automatically provide token expiration, refresh tokens, or a complete multi-device token-management workflow. These requirements may call for additional implementation or a different authentication solution.

14. Common Errors and Solutions

Error 1: 401 Unauthorized

Possible cause: Missing or invalid authentication credentials.

Solution: Check the Authorization header, token value, and configured authentication classes.

Error 2: 403 Forbidden

Possible cause: The request is not permitted under the current permission policy.

Solution: Review the permission classes and the user's authorization. Exact status behavior may vary with authentication configuration.

Error 3: Invalid token

Possible cause: The token does not exist or is incorrect.

Solution: Generate or retrieve the correct token and ensure it belongs to the intended user.

Error 4: No module named rest_framework.authtoken

Possible cause: DRF is not installed correctly or the token application is missing from INSTALLED_APPS.

Solution: Install Django REST Framework, add rest_framework.authtoken, and run migrations.

Error 5: Token endpoint returns an error

Possible cause: The username or password is incorrect, the user does not exist, or authentication has not been configured correctly.

Solution: Verify the user account, credentials, installed applications, and database migrations.

Error 6: Authenticated user cannot access a record

Possible cause: The permission policy or queryset excludes the requested record.

Solution: Check the endpoint's permissions and queryset restrictions. A valid token does not guarantee access to every record.

Error 7: Browser request fails because of CSRF

Possible cause: Session Authentication is being used for an unsafe request without the required CSRF token.

Solution: Follow Django's CSRF protection requirements for session-authenticated browser requests.

15. Frequently Asked Questions (FAQs)

Q1. What is authentication in DRF?

Authentication identifies the user or client making an API request.

Q2. What are permissions in DRF?

Permissions determine whether the requester is allowed to access a view or perform an operation.

Q3. What is Token Authentication?

Token Authentication allows clients to authenticate API requests using a token instead of sending their username and password with every request.

Q4. What does IsAuthenticated do?

It requires the requester to be authenticated.

Q5. What is the difference between IsAdminUser and IsAuthenticated?

IsAuthenticated permits authenticated users, while IsAdminUser checks whether the user has Django's is_staff=True flag.

Q6. Can an API allow public GET requests but restrict POST requests?

Yes. IsAuthenticatedOrReadOnly is one built-in option for allowing anonymous read-only requests while requiring authentication for unsafe requests.

Q7. Does Token Authentication encrypt data?

No. Authentication tokens do not replace HTTPS. HTTPS protects data while it travels between the client and server.

Q8. Does a valid token provide access to every endpoint?

No. The endpoint's permissions and queryset restrictions still determine what the user can access.

Q9. Does DRF's built-in Token Authentication automatically expire tokens?

No. Automatic token expiration is not provided by the basic built-in token system.

16. Django REST Framework Interview Questions and Answers

Q1. What is the difference between authentication and authorization?

Answer: Authentication verifies identity, while authorization determines which resources or operations that identity can access.

Q2. Name four built-in DRF permission classes.

Answer: AllowAny, IsAuthenticated, IsAdminUser, and IsAuthenticatedOrReadOnly.

Q3. How do you configure Token Authentication?

Answer: Add rest_framework.authtoken to INSTALLED_APPS, run migrations, configure TokenAuthentication, and provide a way to obtain tokens.

Q4. How is a token sent to a DRF API?

Answer: Through the HTTP header Authorization: Token YOUR_AUTH_TOKEN.

Q5. What is the purpose of request.user?

Answer: It provides the user associated with the request after authentication has been processed.

Q6. What is the purpose of IsAuthenticatedOrReadOnly?

Answer: It allows safe read-only requests to everyone and requires authentication for unsafe requests.

Q7. Does IsAdminUser check Django's superuser flag?

Answer: It checks is_staff. Superusers normally have is_staff=True, but a staff user does not have to be a superuser.

Q8. Why are queryset restrictions important?

Answer: They prevent users from retrieving records outside their authorized scope. Authentication alone does not enforce record-level access.

17. Practical Assignment

Build a Secure Student Management API using Django REST Framework.

Requirements:

  1. Create or reuse the Student model.

  2. Create a StudentSerializer.

  3. Configure DRF authentication in settings.py.

  4. Enable built-in Token Authentication.

  5. Create the token endpoint at /api/token/.

  6. Protect the Student ViewSet with IsAuthenticated.

  7. Create a public endpoint using AllowAny.

  8. Create a read-only endpoint using IsAuthenticatedOrReadOnly.

  9. Implement a custom permission that allows only staff users to modify records.

  10. Test requests with a valid token.

  11. Test requests with an invalid token and without credentials.

  12. Check that unauthorized users cannot modify protected records.

  13. Add queryset restrictions if users should see only certain students.

  14. Test all endpoints using the DRF browsable API, Postman, or curl.

Expected Result:

You should have a working Student Management API with configurable authentication, permission-based access control, token authentication, and safer API endpoints.

Conclusion

In this module, you learned how to secure APIs using Django REST Framework Authentication and Permissions. You explored Session Authentication, Basic Authentication, Token Authentication, built-in permission classes, custom permissions, and protected ViewSets.

You also learned how to obtain tokens, send authenticated requests, and restrict API operations according to user permissions.

In the next module, you will learn about Django REST Framework Pagination, Filtering, Searching, and Ordering, including how to build efficient APIs that return manageable, searchable, and well-organized datasets.

←
Post 24 of 29
→