11

Im using django rest framework and the djangorestframework-jwt package to creat JWT tokens for authorization.

On the frontend I can decode the token and get the username, email and user_id. However I would like to retrieve some extra information. For example it would be very convenient if I could get kind which is a field on our authorization model (user model).

I can ofcourse make a separate request to get the user info via a regular APIView. But I'm wondering if it's possible to add some extra params in the JWT body?

1
  • yes you can edit utils.py inside djangorestframework-jwt Commented May 6, 2016 at 10:15

2 Answers 2

10

Using the djangorestframework_simplejwt library

  1. Specify in settings.py the USER_ID_FIELD and ALGORITHM

    SIMPLE_JWT = {
        'USER_ID_FIELD': 'user_id',
        'ALGORITHM': 'HS512',
    }
    

Let's say you want to add fields to the body of TokenObtainPairView which has the following body

Token Obtain Pair body

{
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU5MDk5ODAwMSwianRpIjoiMjZhZThhYTU4YTJiNDU3M2JlMDgxNTMzMzU1ODg4ZmUiLCJ1c2VyX2lkIjoxMX0.-jUCnfpTF-RsqHnuoEgctPpHf1SfYNcYaPs8oo01RvrQBMcyhms5PfWipfYkaR0FlPHSTKncNeMxomwd4k7nyg",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTExOTAxLCJqdGkiOiI5NjZkOTFhNzEzNjg0NjMyOGUzYWU3NThiNzNiZmYxMyIsInVzZXJfaWQiOjExfQ.LiHrekmlHrM7_5187ghpIaA6mKcPCjDz4MDKPXHc4QAKVGvcJCJpCjrODCB4-pZn4Kuai5ht3YjWwYSirxpsXw"
}
  1. Add in your urls.py

    path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain'),
    
  2. Create the MyTokenObtainPairView

    class MyTokenObtainPairView(TokenObtainPairView):
        serializer_class = MyTokenObtainPairSerializer`
    
  3. Create the MyTokenObtainPairSerializer

    class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
        def validate(self, attrs):
            data = super().validate(attrs)
            refresh = self.get_token(self.user)
            data['refresh'] = str(refresh)
            data.pop('refresh', None) # remove refresh from the payload
            data['access'] = str(refresh.access_token)
    
            # Add extra responses here
            data['user'] = self.user.username
            data['kind'] = self.user.kind
            data['date'] = datetime.date.today()
            return data
    

This way when you post to /api/token/ you'll get in the body something like this

{
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTEwNTc0LCJqdGkiOiIwM2Q5MzA1NTZmNzk0NmFjODU1MzJlNTYzNjUwZDY0MCIsInVzZXJfaWQiOjExfQ.H0huO84qtzdbo4OkKhsW_vtNTGwInG67gum6f138h1y66EiyZ1BvxaxbfEE2oPG4pB0XjiWQrXc5PlR9C6UvfQ",
    "user": "tiago",
    "kind": "whatever_this_has"
    "date": "2020-05-31"
}
Sign up to request clarification or add additional context in comments.

4 Comments

Is this mentioned in the documentation?
@KrishnadasPC not that I know of
Martin How did you find this then? the code works for me but couldn't find this anywhere else.
@KrishnadasPC it came in a moment I wanted to add to both body and claims. See also this one and this one.
1

As detailed in this github issue, I did this by subclassinng the ObtainJSONWebToken class from DRF-JWT:

from rest_framework_jwt import views as jwt_views
from .serializers import UserSerializer 

class UserLoginViewJWT(jwt_views.ObtainJSONWebToken):
    user_serializer_class = UserSerializer

    def post(self, request, *args, **kwargs):
        response =  super().post(request, *args, **kwargs)

        if response.status_code == status.HTTP_200_OK:
            user = get_user_model().objects.get(email=request.data[get_user_model().USERNAME_FIELD])
            serialized_user = self.user_serializer_class(user)
            response.data.update(serialized_user.data)
        return response

Note: the code above is probably missing some imports

A reply from @jpadilla also specified that

You can also do this with the JWT_RESPONSE_PAYLOAD_HANDLER setting. http://getblimp.github.io/django-rest-framework-jwt/#jwt_response_payload_handler

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.