[Django]-Customizing JWT response from django-rest-framework-simplejwt

55๐Ÿ‘

  • For example: to customize simpleJWT response by adding username and groups,

enter image description here

  1. Override the validate method in TokenObtainPairSerializer
# project/views.py

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)

        # Add your extra responses here
        data['username'] = self.user.username
        data['groups'] = self.user.groups.values_list('name', flat=True)
        return data


class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer
  1. replace the login view with customized view
# project/urls.py

from .views import MyTokenObtainPairView

urlpatterns = [
    # path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
]

๐Ÿ”š

References๏ผš SimpleJWT Readme and the source code as below:
enter image description here

๐Ÿ‘คC.K.

12๐Ÿ‘

A very clean approach from the django-rest-framework-simplejwt README as below

For example, I have users app where my custom User model resides. Follow serializers and views code example below.

users/serializers.py:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        # Add custom claims
        token['name'] = user.name
        # Add more custom fields from your custom user model, If you have a
        # custom user model.
        # ...

        return token

users/views.py:

from rest_framework_simplejwt.views import TokenObtainPairView


class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

After that, Register above View in your projectโ€™s urls.py replacing original TokenObtainPairView as below.

from users.views import MyTokenObtainPairView

urlpatterns = [
    ..
    # Simple JWT token urls
    # path('api/token/', TokenObtainPairView.as_view(),
    #      name='token_obtain_pair'),
    path('api/token/', CustomTokenObtainPairView.as_view(),
         name='token_obtain_pair')
    ..
]

Now get access token and decode it at jwt.io

๐Ÿ‘คJay Modi

3๐Ÿ‘

Custom Token response like this:

from rest_framework_simplejwt.tokens import RefreshToken
    
    
    class LoginView(APIView):
        permission_classes = (AllowAny,)
     
        def post(self, request, *args, **kwargs):
            # ...
    
            # Get user token, include refresh and access token
            token = RefreshToken.for_user(user) 
    
            # Serializer token if it is not correct JSON format ^^
        
            return JsonResponse({'success': 'true', 'token': token, 'user': user})
๐Ÿ‘คHuy Chau

0๐Ÿ‘

I had the same issue this can be resolved by something like this if you want to handle the custom response in case of an invalid credential.

# JWT View
class LoginView(TokenObtainPairView):
    '''
    Returns access token and refresh token on login
    '''
    permission_classes = (AllowAny,)
    serializer_class = MyTokenObtainPairSerializer
    
    def post(self, request, *args, **kwargs):
        try:
            response = super().post(request, *args, **kwargs)
            return response
        except exceptions.AuthenticationFailed:
            return Response({
            'error': True,
            'message': 'Invalid Username or Password',
        }, status=status.HTTP_401_UNAUTHORIZED)
๐Ÿ‘คsid10on10

Leave a comment