Search code examples
pythondjangodjango-rest-frameworkjwtdjango-rest-framework-simplejwt

Adding claims to DRF simple JWT payload


Using djangorestframework_simplejwt library, when POST to a custom view

#urls.py
path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain'),

#views.py
class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

I'm able to get a the following access token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTEwNjg0LCJqdGkiOiI3M2MxYmZkOWNmMGY0ZjI3OTY4MGY0ZjhlYjA1NDQ5NyIsInVzZXJfaWQiOjExfQ.5vs0LmNGseU6rtq3vuQyApupxhQM3FBAoKAq8MUukIBOOYfDAV9guuCVEYDoGgK6rdPSIq2mvcSxkILG8OH5LQ

By going to https://jwt.io/ I can see the payload is currently

{
  "token_type": "access",
  "exp": 1590910684,
  "jti": "73c1bfd9cf0f4f279680f4f8eb054497",
  "user_id": 11
}

JWT

So, we can see that the second part of the token is the payload - containing the claims.

I've explored how to add more information to the Response body and now would like to know how to customize the Payload data by adding iat claim, username and today's date.


Solution

  • As you already created a subclass for the desired view (MyTokenObtainPairView) and a subclass for its corresponding serializer (MyTokenObtainPairSerializer), add the following to the serializer

    class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    
        ...
    
        @classmethod
        def get_token(cls, user):
            token = super().get_token(user)
    
            # Add custom claims
            token['iat'] = datetime.datetime.now()
            token['user'] = user.username
            token['date'] = str(datetime.date.today())
    
            return token
    

    Then, when you POST to that same location, you'll get an access token like this

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTE0MTk4LCJqdGkiOiJhZDZmNzZhZjFmOGU0ZWJlOGI2Y2Y5YjQ4MGQzZjY2MiIsInVzZXJfaWQiOjExLCJpYXQiOjE1OTA5MTc0OTgsInVzZXIiOiJ0aWFnbyIsImRhdGUiOiIyMDIwLTA1LTMxIn0.-5U9P-WWmhlOenzCvc6b7_71Tz17LyNxe_DOMwwqH4RqrNsilVukEcZWFRGupLHRZjIvPya2QJGpiju9ujzQuw
    

    Using JWT you can see the Payload changing accordingly

    Custom Payload simpleJWT Django

    {
      "token_type": "access",
      "exp": 1590914198,
      "jti": "ad6f76af1f8e4ebe8b6cf9b480d3f662",
      "user_id": 11,
      "iat": 1590917498,
      "user": "tiago",
      "date": "2020-05-31"
    }