Customizing JWT response from django-rest-framework-simplejwt
- For example: to customize simpleJWT response by adding username and groups,
- Override the
validate
method inTokenObtainPairSerializer
# project/views.pyfrom rest_framework_simplejwt.serializers import TokenObtainPairSerializerfrom rest_framework_simplejwt.views import TokenObtainPairViewclass MyTokenObtainPairSerializer(TokenObtainPairSerializer): def validate(self, attrs): data = super().validate(attrs) refresh = self.get_token(self.user) data['refresh'] = str(refresh) data['access'] = str(refresh.access_token) # Add extra responses here data['username'] = self.user.username data['groups'] = self.user.groups.values_list('name', flat=True) return dataclass MyTokenObtainPairView(TokenObtainPairView): serializer_class = MyTokenObtainPairSerializer
- replace the login view with customized view
# project/urls.pyfrom .views import MyTokenObtainPairViewurlpatterns = [ # 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:
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 TokenObtainPairSerializerclass 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 TokenObtainPairViewclass 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 MyTokenObtainPairViewurlpatterns = [ .. # 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
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})