Django: User Authentication using knox

Django: User Authentication using knox:

 To get started, make sure you have django installed by using the command pipenv install django in your terminal. (Make sure you are in a virtual environment: pipenv shell)

Create a project django-admin startproject . For this example, I will be creating a project about tvshows! So, my command will be django-admin startproject tvshows.

Now, cd into your project and make sure manage.py is in your root directory.

The command python manage.py runserver allows your app to be up and running. http://127.0.0.1:8000/ on your browser, should show this:

Next, create a superuser:python manage.py createsuperuser
This asks for a username, password and email address. Now that you have created a superuser, on the browser, add /admin to your initial site like this: http://127.0.0.1:8000/admin and your browser should show:

Use the username and password used to create the superuser to login! you should then see:

Now, you are ready to create user auth using knox where a token is generated for a user to login and access data.
You need to install the following:
pipenv install djangorestframework
pipenv install django-rest-knox

In settings.py, add:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'knox'
]

Now, let’s create an app for our project.
Use python manage.py startapp  in the terminal. For now, I’ve used python manage.py startapp backend.

Your files in your code editor should look something like this:

Starting with Registration API:

In the backend folder, create a new file and name it serializers.py and add:

from rest_framework import serializers
from django.contrib.auth.models import User
from django.contrib.auth import authenticate

class CreateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'password')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User.objects.create_user(validated_data['username'],
                                        None,
                                        validated_data['password'])
        return user

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username')

Then, create an api.py file in the backend folder and add:

from rest_framework import viewsets, permissions, generics
from rest_framework.response import Response
from knox.models import AuthToken
from .serializers import CreateUserSerializer, UserSerializer

class RegistrationAPI(generics.GenericAPIView):
    serializer_class = CreateUserSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })

Now, to add the endpoints, create a urls.py file in the backend folder and add:

from django.urls import path
from .api import RegistrationAPI
from knox import views as knox_views

urlpatterns = [
    path('register/', RegistrationAPI.as_view()),
]

You also need to add endpoint in urls.py file in the project folder which is tvshowsin this case:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('backend.urls')),
    path('api/auth/', include('knox.urls'))
]

Registration API is now complete. Next is creating a Login API.

In the serializers.py in your backend folder, add:

class LoginUserSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, data):
        user = authenticate(**data)
        if user and user.is_active:
            return user
        raise serializers.ValidationError("Invalid Details.")

Next, in api.py add:

from .serializers import CreateUserSerializer, UserSerializer, LoginUserSerializer

class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginUserSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })

You need to add the endpoints in urls.py in the backend folder:

from .api import RegistrationAPI, LoginAPI

urlpatterns = [
    ...,
    path('login/', LoginAPI.as_view()),
]

Finally, you need an API to shows the user data when the user successfully logs in. To do this, you need to create a class in api.py file in your backend folder:

class UserAPI(generics.RetrieveAPIView):
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user

This needs an endpoint too. Therefore, in your urls.py in your backend folder, add:

from django.urls import path
from .api import RegistrationAPI, LoginAPI, UserAPI
from knox import views as knox_views

urlpatterns = [
    path('register/', RegistrationAPI.as_view()),
    path('login/', LoginAPI.as_view()),
    path('user/', UserAPI.as_view()),
]

Now, you’re all set. Make sure you run those migrations, using python manage.py makemigrations followed by python manage.py migrate.

You can use Postman to check if your endpoint work and you’re able to do GET and POST requests.

Let’s start with registration. You need to add header and a body to create a new user. So using the url http://127.0.0.1:8000/api/register/, add key Content-Type and value application/json on the header like this:


And add the body to POST to the API, like this:


Your registration has been successful!

You can now log in using http://127.0.0.1:8000/api/login/ and POST methodadding the same body used to register. This generates a token:

You cannot access the user details without passing the token that was generated when successfully logging in, as seen below:


You are unable to view the user detail.

Therefore, you need to pass the token like this:

You are now able to view the user detail:

You can also see if the user was successfully created on django admin:

bhuma08 was the superuser I created at the beginning and user1 was created using Postman.

That’s the end! 🙂

from Tumblr https://generouspiratequeen.tumblr.com/post/635381438044307456

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s