How to customize the default Token invalid json response in django for JWTAuthentication

80 Views Asked by At

In my django rest app i like to change the default error response from JWTAuthentication. Currently my application is using JWT With django to work on login and logout (which blacklists the token). Below is my code.

settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

account app views.py

from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken, BlacklistMixin

class BlacklistRefreshTokenView(APIView, BlacklistMixin):

    def post(self, request):
        token = RefreshToken(request.data.get('token'))
        token.blacklist()
        # return Response({'message': 'Token blacklisted successfully.'})
        return json_response('Logout successful', None, 200)

class CustomTokenObtainPairView(TokenObtainPairView):
     def post(self, request, *args, **kwargs):

         # Call the base class's post method to continue with the login process
         response = super().post(request, *args, **kwargs)

         return response

urls.py

from django.urls import path
from .views import CustomTokenObtainPairView, BlacklistRefreshTokenView

urlpatterns = [
    path('login/', CustomTokenObtainPairView.as_view(), name="login"),
    path('logout/', BlacklistRefreshTokenView.as_view(), name='blacklist_token'),
]

response im getting when token is invalid

{
    "detail": "Given token not valid for any token type",
    "code": "token_not_valid",
    "messages": [
        {
            "token_class": "AccessToken",
            "token_type": "access",
            "message": "Token is invalid or expired"
        }
    ]
}

expected response

{
    "message": "Given token not valid for any token type",
    "status": "401"
}
2

There are 2 best solutions below

0
Yash Marmat On BEST ANSWER

So, I was able to achieve the same by following exception topics in Django rest framework. So, to have our custom exception response for every single response in our Django project, we need to update the REST_FRAMEWORK field in the project's settings.py file. An example below:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
2
Yusuf Ertas On

I think what you are trying to get at is this:

from django.http import JsonResponse
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.exceptions import TokenError
from rest_framework_simplejwt.tokens import RefreshToken, BlacklistMixin
from rest_framework_simplejwt.views import TokenObtainPairView


class BlacklistRefreshTokenView(APIView, BlacklistMixin):

    def post(self, request):
        token = RefreshToken(request.data.get("token"))

        try:
            _ = RefreshToken(token)
            token.blacklist()
            return JsonResponse('Logout successful', None, 200)
        except TokenError:
            return Response(data={
                "message": "Given token not valid for any token type",
                "status": "401"
            }, status=status.HTTP_401_UNAUTHORIZED)


class CustomTokenObtainPairView(TokenObtainPairView):
    def post(self, request, *args, **kwargs):
        # Call the base class's post method to continue with the login process
        response = super().post(request, *args, **kwargs)

        return response