How To Create A Custom Token Auth Using Python

#5 Python Weekly

ยท

3 min read

How To Create A Custom Token Auth Using Python

Hello there ๐Ÿ‘‹,

Today I am going to talk about a recent feature I struggled to implement on Django Rest Framework ( DRF). I aimed to prevent multiple device login, it may seem easy but it wasn't for a week. I tackled this for a week. I got lots of ideas, code, etc. None worked and it got so bad that the more I tried, the more I caused pain to my codebase. I cried a lot ๐Ÿ˜‚ but in the end, I pulled through with the help of a friend so I will also share my knowledge in this article.

Let's start ๐Ÿš€

1. LoginView

The LoginView control displays different Web site content templates (or "views") for different users, based on whether the user is authenticated and, if so, which Web site roles they belong to.

The template stored in this view is shown to the user when they haven't logged in. The LoginView control manages to switch among the various templates once you assign templates.

Below is an example of what a LoginView Django code looks like:

Views.py

#loginView
from django.contrib.auth.views import LoginView    

class AdminLogin(LoginView):
    template_name = 'LoginView_form.html'

Template_name: the template that would display the login form.

Urls.py

#LoginView
path('login/', AdminLogin.as_view(), name="login")

Settings.py

LOGIN_REDIRECT_URL = 'home' # URL redirecting after a successful authentication

This redirects the user (after successfully logging in) to a homepage.

You created a class-based view and called LoginView to override the built-in login system by Django. If your code works you should see your homepage after you click the login button.

2. dj_rest_auth.views

The dj_rest_auth.views handle the authentication in DRF (Django Rest Framework) and it works especially well with SPAs (e.g React, Vue, Angular), and Mobile applications. It provides endpoints for:

  • User registration with optional activation

  • Login and Logout

  • Retrieve and update Django User model

  • Password change

  • Password reset via e-mail

  • Social media auth authentication.

Okay, now we what LoginView and dj_rest_auth.views are and how it works. I will now explain how to solve my problem.

Import LoginView

First, I imported LoginView from dj_rest_auth.views. I wrote it like this:

from dj_rest_auth.views import LoginView

Create class-based view

Next, I created a class-based view in my views.py and called the original serializer for LoginView. For the class-based view, I set the token to reset each time a user logs in and the old token will be deleted and the new token will be returned through the endpoint and saved on the database.

class CustomAuthToken(LoginView):
    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"]
        user.auth_token.delete()
        token, created = Token.objects.get_or_create(user=user)
        return Response(
            {
                "key": token.key,
                "message": "Old Token Deleted"

            },
            status=status.HTTP_200_OK
        )

Before it changes the user's token, it first validates that said user is registered and saved on the database. That is what user = serializer.validated_data["user"] does.

The next line deletes the old token while the next line creates a new token and saves it.

return Response: returns the new token and a message that say old key deleted

Urls.py

Next is to add to the urls.py of your project's file

 path('auth/signin/', CustomAuthToken.as_view(), name='customsignin')

The above code created a custom authentication backend code that deletes a user token after a user signs in.

That's all. I just explained how to create a custom backend authentication that changes user token after login/sign in.

Keep in touch:

Thanks for reading till the end โค๏ธ.

You can contact me via email and/or Discord:

Email -

Discord - Sophyia#8929

ย