Search code examples
djangodjango-rest-frameworkdjango-rest-framework-simplejwt

Django JWT authentication TokenObtainPairView issue


I am trying to use CustomTokenObtainPairView to receive my username in token.

views:

if user.check_password(password):
            # refresh = RefreshToken.for_user(user)
            # refresh.access_token['username'] = user.username
            # token = str(refresh.access_token)
            request.data = {
                'username': username,
                'password': password
            }
            token_response = CustomTokenObtainPairView.post(request=request.data)


            response = Response()
            response.set_cookie(key='jwt', value=token_response.data['access'], httponly=True,     
            secure=True)
            response.data = {
                'access': token_response.data['access']
            }
            return response
        else:
            return Response({'message': 'Wrong password!'}, status=400)

I tried to generate token and adding username in it but it didnot work. If anybody knows how to use TokenObtainPairView in correct way in your function please help.


Solution

  • If you want to change the token claims, you should customize TokenObtainPairSerializer.
    my_app/serializers.py
    from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
    from rest_framework_simplejwt.tokens import Token
    
    
    class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
        @classmethod
        def get_token(cls, user) -> Token:
            token = super().get_token(user=user)
            token["username"] = user.username
            return token
    
    settings.py
    ...
    SIMPLE_JWT = {
      "TOKEN_OBTAIN_SERIALIZER": "my_app.serializers.MyTokenObtainPairSerializer",
    }
    ...
    
    If you want to change the way you serve tokens (you may want to use cookies), you should customize the TokenObtainPairView or the TokenRefreshView.
    my_app/views.py
    from rest_framework import status
    from rest_framework.request import Request
    from rest_framework.response import Response
    from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
    from rest_framework_simplejwt.views import TokenObtainPairView
    
    
    class CustomTokenObtainPairView(TokenObtainPairView):
        def post(self, request: Request, *args, **kwargs) -> Response:
            serializer = self.get_serializer(data=request.data)
            try:
                serializer.is_valid(raise_exception=True)
            except TokenError as e:
                raise InvalidToken(e.args[0])
    
            response = Response(data=None, status=status.HTTP_200_OK)
            response.set_cookie(key="access", value=serializer.validated_data["access"], httponly=True, secure=True)
            response.set_cookie(key="refresh", value=serializer.validated_data["refresh"], httponly=True, secure=True)
            return response
    
    
    urls.py
    from my_app.views import CustomTokenObtainPairView
    
    urlpatterns = [
        ...
        path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
        ...
    ]
    
    You can do the same for your TokenRefreshView.