Token Authentication in Django Rest Framework

Let's say we had setup an API to accept POST request(the purpose of the endpoint here is not important), and we want to authenticate each request and deny access to the endpoint for those who is unauthorized.

Adding Token Authentication Mechanism

This snippet is our views.py, we have a Class-based View inherited from APIView (a View in Django Rest Framework):

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

class BuildTrigger(APIView):
    """
    This Endpoint accept only POST request to trigger something...
    """

    def post(self, request):
      # do something
      return Response(None, status=200)

To plug in the authentication mechanism of Django Rest Framework(DRF) is fairly simple.

First, add this into your settings.py:

INSTALLED_APPS = [
    # Your other apps
    'rest_framework.authtoken',
]

After adding rest_framework.authtoken into your INSTALLED_APPS, run migration to make appropriate updates to your database:

$ python manage.py migrate

Add 2 lines of code into your View class:

# Add these import statements
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated

class BuildTrigger(APIVIew):
    authentication_classes = (TokenAuthentication,) # Add this line
    permission_classes = (IsAuthenticated,)         # Add this line

    # Your remaining code

If you run your project and access to your endpoint, you will get an error message below:

'Authentication credentials were not provided.''

There are 2 steps involved in order to gain access to the endpoint:

  1. Generate a Token
  2. Supplying the Token

Generating Your Token

Before generating a Token, make sure you have your User created. The User I referred is the django.contrib.auth.models.User

If you have previously created a superuser, your User data will be stored in this model.

To generate a Token, you can fire up your Python shell with appropriate Django settings loaded. To do all these, simply run the following command in your shell:

$ python manage.py shell

After that, import your User model and Token model (Token model stores all the associated tokens):

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

Now, get the instance of your User:

user = User.objects.get(username="your_username")

Create a Token:

# Make sure you obtained your User instance
token = Token.objects.create(user=user)

Obtain your Token:

token.key  

# Result will be some sort of hash:
'caff37f830e5bd8283830ad5fc5f1aa226120cb8'

Alternative: Creating a Token using Django manage.py command

Alternatively, you can generate a token using the manage.py command:

$ python manage.py drf_create_token -r <your_username>

Using Your Token

To use your token, simple add the key Authorization with value Token <your_token_here> in your HTTP header.

You can test your token with curl :

curl -X GET http://127.0.0.1:10000/api/ -H 'Authorization: Token caff37f830e5bd8283830ad5fc5f1aa226120cb8'

In my case, I use Postman to test my API.

authenticating_access_with_token_1

Now you should be able to access your endpoint.

First published on 2017-10-24

No Comments Yet