Overriding the Serializer Class of JWT create end point ( Providing a custom serializer )
So, I'was using rest_framework_simplejwt for jwt auth in my project, with a custom TokenObtainPairSerializer to extend the support of creating token with email & password also.
Here is the serializer
class CustomTokenPairSerializer(TokenObtainPairSerializer):
def validate(self, data):
try:
user = User.objects.filter(username=data.get("username")) or \
User.objects.filter(email=data.get("username"))
except User.DoesNotExist:
raise serializers.ValidationError("No such user exists")
credentials = {
"username": "",
"password": data.get("password")
}
if user:
user = user.first()
credentials["username"] = user.username
return super().validate(credentials)
and the endpoint to this is
path(
'token/',
TokenObtainPairView.as_view(
serializer_class=CustomTokenPairSerializer,
permission_classes=(AllowAny, )
),
name='token_obtain_pair'
),
then I include the djoser I found no way to override the Serializer, I included the same endpoint as djoser-jwt-create with my custom serializer but it isn't working.
I know the url matching takes place from start to end, but I did not get the desired result.
path('api/v1/auth/jwt/create', TokenObtainPairView(
serializer_class=CustomTokenPairSerializer,
permission_classes=(AllowAny, )
).as_view(), name='jwtt-create'),
path('api/v1/auth/', include('djoser.urls')),
path('api/v1/auth/', include('djoser.urls.jwt')),
Thank You.
I don't know if the class CustomTokenPairSerializer that you make is working, I'm not testing yet. but if you want to make a custom token. you can do this... this work on my project.
create new file serializers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class TokenObtainSerializer(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)
data["test"] = "value"
return data
class CutomObtainPairView(TokenObtainPairView):
serializer_class = TokenObtainSerializer
and then in your urls.py
from accounts.serializers import CutomObtainPairView
urlpatterns = [
path('admin/', admin.site.urls),
path('auth/jwt/create/', CutomObtainPairView.as_view(), name='customtoken'),
path('auth/', include('djoser.urls')),
path('auth/', include('djoser.urls.jwt')),
]
you will get the result like this :
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXB...........",
"access": "eyJ0eXAiOiJKV1QiLCJh........bGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIj.",
"test": "value"
}
If you want to return the data inside the token change the serializer as below:
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token["email"] = user.email
token["userRole"] = user.role
return token