Token Authentication in Django Rest Framework
Published: 2021-08-22 19:44:20

Authentication is the mechanism of associating an incoming request with some credentials that would be later used to determine whether the credentials is valid or not and might be frequently used to determine if the user has the permission for the request.

One of the most widely used authentication mechanism is Token Authentication. In this article we would explore Token Authentication and how to setup token authentication in Django Rest Framework. Token Authentication is appropriate for client-server setups for example native desktop clients or mobile clients or it might be used for web clients.

Token Authentication is an authentication process in which the verification of a user is done using a token. This token is a long string of random numbers and English letters. It is generated when a user registers to a system. Every time the user signs in, the server provides him this token along with other information. This token is provided in every request that requires an associated user. (if an API endpoints does not need to verify user, then it’s not required to provide it, for example: sign in, sign up requests doesn’t need it). Server receives this token before doing the usual stuff that it needs to do for the request and verifies the user.

How to use it in Django Rest Framework

Configuring settings :

To use Token Authentication we need some configuration in our django project’s settings file.

First we need to add TokenAuthentication in authentication classes.

```python
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        ...
        'rest_framework.authentication.TokenAuthentication',
    ]
}
```

Next, we need to include rest_framework.authtoken in our INSTALLED_APPS settings.

```python
INSTALLED_APPS = [
    ...
    'rest_framework.authtoken'
]
```

Now, rest_framework.authtoken provides database migrations. So, we need to run manage.py migrate command.

Generating a token :

Next up, we need to create a token when a user registers in our system. Creating a token is very simple .

```python
from rest_framework.authtoken.models import Token
 
token = Token.objects.create(user=...)
print(token.key)
```

This way the token is created for the user. But the way we are creating the tokjen right now won’t serve our use case. We need to create the token only when the user registers or when a new user object is created. To do that, we can use django signals. The post_save signal is just perfect for that. We can detect if the user instance is created or updated using the created parameter. If the user is created then we would create the token for that user.

```python
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
 
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)
```

Now, this is not the only way to do that. For example we can generate this token when it needs to be accessed for the first time using django ORM’s get_or_create(). We can do the same thing if we already have some existing users.

Using the token in requests :

We have generated the token for a user, but how would we use it our requests. The answer is simple. We would pass it in Authorization HTTP header. The token key should be prefixed by “Token” string and a white-space separating them.

```curl
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
```

API Endpoint to retrieve token using credentials :

Now, we may need an api endpoint that would return the user his token when username and password is provided. Django Rest Framework already does that for us. We can use it’s built in view to create that api endpoint.

```python
from rest_framework.authtoken import views
 
urlpatterns = [
    path('api-token-auth/', views.obtain_auth_token)
]
```

Now, this endpoint would return a JSON response containing then token. But, if we ever need a custom response we can either subclass DRF’s ObtainAuthToken or create a custom API view that would do the work for us.

Procedure of subclassing the ObtainAuthToken view and returning a custom response is like this:

```python
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
 
class CustomAuthToken(ObtainAuthToken):
 
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'username': user.username,
            'email': user.email
        })
```

Now in our urls.py file we can add a route for this view and use it same as the builtin view, but this time the response would be customized.

That is it for Token Authentication in DRF. This article was based on Django Rest Framework’s documentation. Read the documentation for more in-depth understanding and also you can dig deep into other Authentication schema as well.