9. TokenAuthentication

The token authentication works by exchanging username and password for a token that will be used in all subsequent requests so to identify the user on the server side.

Token authentication is suitable for client-server applications, where the token is safely stored. You should never expose your token, as it would be (sort of) equivalent of a handing out your username and password.

There are various 3rd party packages for Token authentication

9.1 Django-rest-auth

Doc: https://github.com/Tivix/django-rest-auth

View CODE here: https://github.com/amrit94/drf-test/tree/11-TokenAuth-Django-rest-auth

Code Difference: https://github.com/amrit94/drf-test/commit/787b157a3f84f2626994652181c10424d3c80559

9.1.1 Enable TokenAuthentication

To enable TokenAuthentication - add below lines and run migration

# setting.py
INSTALLED_APPS += [
    'rest_framework.authtoken'
]

# views.py
authentication_classes = (TokenAuthentication,)
permission_classes = [permissions.IsAuthenticatedOrReadOnly]

9.1.2 Generating Tokens

Token can be generated in different way as described below:

1. Using Django manage.py command

The easiest way to generate a token, just for testing purpose, is using the command line utility again

# Generate
python manage.py drf_create_token localadmin

# Output
Generated token 261263a45xxxxxxxx for user localadmin

# Re-Generate
python manage.py drf_create_token -r localadmin

2. By exposing an api endpoint

The DRF provide an endpoint for the users to request an authentication token using their username and password.

  • Make POST request with username and password
    • PATH: POST
    • /api-token-auth/
    • With Body > form-data: username and password
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns += [
    path('api-token-auth/', obtain_auth_token, name='api-token-auth'),
]

3. By using signals

If you want every user to have an automatically generated Token, you can simply catch the User’s post_save signal.

4. With Django admin

It is also possible to create Tokens manually through the admin interface.

Endpoints

Access Resources

Using the Token in Header section you can access all the endpoints

  • PATH: GET /tracks/
    • Header > Authorization: Token 261263a45xxxxxxxx

Generate new token

If the old token is compromised then you need generate new token as described below

  1. Authenticate the user
  2. Delete old token if exist
  3. Create new token
  4. Return token is response
# views.py
from rest_framework.decorators import api_view, authentication_classes
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework import status

@api_view(['GET'])
@authentication_classes([TokenAuthentication])
def get_new_token(request):
    if request.user.is_authenticated:
        user_obj = request.user
        token_obj, is_created = Token.objects.get_or_create(
            user=user_obj)
        if not is_created:
            print(token_obj)
            token_obj.delete()
            token_obj, is_created = Token.objects.get_or_create(
                user=user_obj)
            print(token_obj)
        return Response({'token': token_obj.key})
    return Response({"detail": "User not authenticated"},
                    status=status.HTTP_400_BAD_REQUEST)
  • PATH: GET /api-token-auth/new/
    • Header > Authorization: Token 261263a45xxxxxxxx
# urls.py
path('api-token-auth/new/', get_new_token, name='new_token'),