Solution to How Token Authentication is implemented in Django REST Framework for Django 3.x.x and Django 2.x.x - Sikademy

Nov. 27, 2020

Archangel Macsika Sikademy Image

Archangel Macsika

How Token Authentication is implemented in Django REST Framework for Django 3.x.x and Django 2.x.x

What is token authentication and how does it work?

The token authentication in Django is an authentication method that operates by swapping username and password for a unique token.

This token will be used to identify a specific user on the server-side in all subsequent requests that will be made while using the site.

Token authentication is best used for client-server applications, where the token can be securely stored and prevented from being exploited.

Unauthorized access to a token is equivalent to unauthorized access to a username and password.

Diving into the nitty-gritty of how the authentication is handled on the client-side is quite complicated as it depends on the technology, language, or framework being used.

The client could be a mobile application using iOS or Android or a desktop application using C++ or Java. It could also be a Web application using PHP, Go, or Ruby.

This tutorial shows you how to carry out token-based authentication using Django REST Framework from a freshly created django project.

Django Version: Django 3.1.

O.S Platform: MacOs Mojave.

Set Up a Django REST Framework API Project

We will begin by installing Django and Django REST Framework (DRF):


pip install django
pip install djangorestframework

Next, we want to create a new Django REST Framework project and navigate to it:


django-admin.py startproject djangoauthenticate . && cd djangoauthenticate

Create a new app:


django-admin.py startapp tokenapp

Here is what your project structure should look like:



djangoauthenticate/
     tokenapp/
          __init__.py
          admin.py
          apps.py
          migrations/
              __init__.py
          models.py
          tests.py
          views.py
     __init__.py
     settings.py
     urls.py
     asgi.py
     wsgi.py
manage.py

Add the created tokenapp app and the installed rest_framework app to the INSTALLED_APPS section in the settings.py file of the django project:

djangoauthenticate/settings.py



INSTALLED_APPS = [
    # Django Apps
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Third-Party Apps
    'rest_framework',

    # Personal Apps
    'djangoauthenticate.tokenapp',
]


Next, we want to migrate the database:


python manage.py makemigrations
python manage.py migrate

Let’s create our first Django Rest API view:

djangoauthenticate/tokenapp/views.py


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

class HomeView(APIView):
    def get(self, request):
        content = {'message': 'Hello, World!'}
        return Response(content)

Next, set up a URL path to be used.

djangoauthenticate/urls.py


from django.urls import path
from djangoauthenticate.tokenapp import views

urlpatterns = [
    path('home/', views.HomeView.as_view(), name='home'),
]

Run the server and visit the URL http://127.0.0.1:8000/home/.


python manage.py runserver

You should see the image below which shows we successfully create a Django REST API Endpoint.

image showing Django REST API authentication page created successfully

To receive the response as plain JSON data:


http://127.0.0.1:8000/home/?format=json

You can also run any of the codes below on a command-line to access the Django REST API Endpoint.

You can use cURL, which is widely available on all major Linux/macOS distributions:


curl http://127.0.0.1:8000/home/

We can also use the Python command line tool HTTPie:


http http://127.0.0.1:8000/home/

Your output for both cURL and HTTPie will be the same as the data in the browser but more elaborate and sophisticated with added details.

Next, we will secure the Django REST API endpoint we created so we can carry out the Django REST token authentication:

Take note of the new lines of codes and modifications made.

djangoauthenticate/tokenapp/views.py


from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated  # <- New import added here

class HomeView(APIView):
    permission_classes = (IsAuthenticated,)             # <- New code added here

    def get(self, request):
        content = {'message': 'Hello, World!'}
        return Response(content)

If we run this code on the terminal, we get an HTTP 403 Forbidden error.


http http://127.0.0.1:8000/home/

Setting Up the Django REST API Token Authentication

Now, let’s implement the token authentication so we can access this endpoint.

First, we need to add rest_framework.authtoken to theINSTALLED_APPS in our settings.py file and include the TokenAuthentication in the REST_FRAMEWORK section of the settings.py file.

djangoauthenticate/settings.py



INSTALLED_APPS = [
    # Django Apps
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Third-Party Apps
    'rest_framework',
    'rest_framework.authtoken',  # <-- new code added here

    # Personal Apps
    'djangoauthenticate.tokenapp',
]
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',  # <-- new code added here
    ],
}


Next, we want to migrate the database to create the table that will store the Django REST API authentication token:


python manage.py makemigrations
python manage.py migrate

Next, we will create a Django superuser account we will use to test things out.


python manage.py createsuperuser

Using the user account we just created (username: archangel, email: [email protected], password: Test123), we can get the token for that particular user.

Running the command below gives us a randomly generated alphanumeric string that serves as the token for that user.

This random string 9173g6bb2012f146tcc9933627a1adff517dafcd is what we will use to carry out the token authentication.


python manage.py drf_create_token archangel

Let's see how a token is useful. First, run the code below.


http http://127.0.0.1:8000/home/

You will notice how our Django REST API is now providing some a bunch of new information to the client. Take note of what is shown within the curly brackets.

Now, run the code below with the token authentication. The token string used here will be different from yours, use the one generated for you.


http http://127.0.0.1:8000/home/ 'Authorization: Token 9173g6bb2012f146tcc9933627a1adff517dafcd'

You notice that the message we sent to the view is showing.

And that's it for setting up the Django REST Authentication token. Next, we will handle the user token request.

Specific User Token Authentication Request

Using a regular username and password, Django REST Framework provides an endpoint for the users to request an authentication token.

Let's set up another URL path.

djangoauthenticate/urls.py


from django.urls import path
from rest_framework.authtoken.views import obtain_auth_token  # <- New code added here
from djangoauthenticate.tokenapp import views

urlpatterns = [
    path('home/', views.HomeView.as_view(), name='home'),
    path('token-authenticate/', obtain_auth_token, name='token-authenticate'),  # <- New code added here
]

If we run the code below and inspect this new endpoint, you'll notice that only a POST request is allowed.


http http://127.0.0.1:8000/token-authenticate/

The endpoint doesn’t handle GET requests. It’s simply a view to receiving a POST request with username and password. Let's test this out using the username and password we created earlier.


http post http://127.0.0.1:8000/token-authenticate/ username=archangel password=Test123

The response we will get is the token assigned to this particular user. From this point, you can store this token and use it to authenticate the future requests carried out by this user.

Related Answers

Was this answer helpful?

Join our Community to stay in the know

Get updates for similar and other helpful Answers