Token based, authenticated REST API's using Django Rest Framework (DRF)
Add rest_framework and rest_framework.authtoken to installed apps in Django project settings file
First install DRF
$ pip install djangorestframework
then add the DRF to installed apps,
INSTALLED_APPS = (
# 'django_admin_bootstrapped',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'.....',
)
and run migrations for the DRF,
$ python manage.py makemigrations
$ python manage.py migrate
Token generation code for each new user to be created (in relevent models file)
# models.py
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)
for already existing users, the token can be generated by running the below snippet in django shell
# python manage.py shell
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
for user in User.objects.all():
Token.objects.get_or_create(user=user)
Adding API endpoint for getting tokens
# urls.py
from rest_framework.authtoken import views
from myapp.views import MyView
urlpatterns += [
url(r'^get/my/view/$', MyView.as_view()),
url(r'^token/', views.obtain_auth_token),
]
Adding an API endpoint view under token authentication
For class based views
# views.py
from django.http import JsonResponse
from rest_framework.authentication import TokenAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
class MyView(APIView):
""" subclass from APIView inorder to use the token based authentication provided by DRF"""
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get(self, request):
return JsonResponse({'Data':'My View'})
For function based views
#views.py
from django.http import JsonResponse
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import TokenAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
@api_view(['GET'])
@authentication_classes((TokenAuthentication,))
@permission_classes((IsAuthenticated,))
def my_view(request, format=None):
return JsonResponse({'Data':'My View'})
testing
Once everything has been done, create a user and test if everything works fine.
$ curl -X POST -d 'username=username&password=password' localhost:8000/token/
{"token":"6874e18a8e754df76ab140744c9310142e6f8943"}
$ curl -H "Authorization: Token 6874e18a8e754df76ab140744c9310142e6f8943" http://localhost:8000/get/my/view/
{'Data':'My View'}
$ curl http://localhost:8000/get/my/view/
{"detail": "Authentication credentials were not provided."}