Search Here

Django Rest Framework Handling Based Token Authentication

Django Rest Framework Handling Based Token Authentication

The Django Rest Framework provides many ways to handle API-based token authentication and also the freedom to create your own authentication class.
And in this post, you’ll learn the generate token authentication for users and also authenticate them.

Setting up Django

django-admin startproject drf_one

Setup Database

In drf_one\settings.py.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'drf_one', # database name
        'USER': 'root',
        'PASSWORD': '',
        'HOST': 'localhost',   # Or an IP Address that your DB is hosted on
        'PORT': '3306',
        'OPTIONS': {
            'sql_mode': 'traditional',
        }
    },
}

Note

For django.db.backends.mysql you must first install mysqlclient which is an interface between Python and MySQL databases. Use the command pip install mysqlclient to install it.

Create Django App

use command django-admin startapp users to create an app within the root folder. After this register the app in the settings.py file under INSTALLED_APPS.

INSTALLED_APPS = [
    '....',
    'users.apps.UsersConfig',
]

Also, update the drf_one\urls.py.

urlpatterns = [
    path('users/', include('users.urls')),
]   

Installing Django Rest Framework

Use the below command to install Django Rest Framework

pip install djangorestframework

Configuring Django Rest Framework

After installation simply add rest_framework and rest_framework.authtoken within INSTALLED_APPS. Also, specify default authentication by putting it inside REST_FRAMEWORK dictionary. This is where all the rest_framework settings exist.
In drf_one\settings.py.

INSTALLED_APPS = [
    '....',
    'rest_framework',
    'rest_framework.authtoken',
    'users.apps.UsersConfig',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

Generating Tokens for the Users

To provide auth tokens to the user use Token model by importing from rest_framework.authtoken.models import Token.

In users\views.py

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from django.contrib.auth.models import User
from rest_framework.authentication import TokenAuthentication
from django.contrib.auth.hashers import check_password
from rest_framework.permissions import IsAuthenticated

# Create your views here.
class LoginApiView( APIView ):

    def post(self, request, *args, **kwargs):
        user = User.objects.filter(username=request.POST['username']).first()

        if user and check_password( request.POST['password'], user.password ):
            obj = Token.objects.filter( user_id=user.pk ).first()
            if not obj:
                obj = Token.objects.create( user=user )
            return Response({
                'token' : obj.key
            })
        else:
            return Response({
                'error' : "Incorrect login credentials"
            })
    
#output
{
    "token": "99fbcf233641e12f3d4353d82a1c99d26e4ce63f"
}

Note

The model Token can have only one token of a given user and to create a new token simply delete the existing one.

Specify some URLs to handle incoming requests in users\urls.py

from django.urls import path, include
from users import views

app_name = "users"

urlpatterns = [
    path('<int:pk>',  views.UserInfo.as_view() ),
    path('login',  views.LoginApiView.as_view() ),
]    

Authenticating Users Via Token

For APIView authentication can be specified in authentication_classes which takes an array.
In users\views.py

class UserInfo( APIView ):
    authentication_classes = [ TokenAuthentication ]
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        user = User.objects.get(pk=kwargs['pk'])

        return Response({
            'id' : user.pk,
            'username' : user.username,
            'first_name' : user.first_name,
        })
#output
{
    "id": 2,
    "username": "kunal123",
    "first_name": "Kunal"
}
If the token does not exist during authentication the { "detail": "Invalid token." } with 401 Unauthorized error is raised.

Learn more about Django Rest Framework Token Authentication.

Watch Video

Conclusion

In Django Rest Framework there are various authentication methods available which we’ll be discussing in upcoming posts.