Changing the default user while using REST framework JWT

Viewed 154

I have a proxied user model:

class TheDude(User):
    class Meta:
        proxy = True

And I'm using the Django REST framework JWT to do JWT auth in the REST API.

I'd like to get the user object from the request but currently it's a User object. Because it's proxied I can't use AUTH_USER_MODEL. I've tried doing a middleware component to override the user in the request but it's not set at that stage. I've also tried using JWT_RESPONSE_PAYLOAD_HANDLER however my function isn't called so I can't set it there either.

If I want to be able to get TheDude object when I call request.user instead of User in my views, how would I do this while authing using the REST framework JWT Auth library?

EDIT

I've added

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        ...
        'myapp.authentication.MyCustomJWTAuthentication',
    )
    ...
}

to my settings.py and my

class MyCustomJWTAuthentication(JWTAuthentication):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user_model = TheDude

Which is called correctly however when I get the user from request in my serialiser, it's still of type User and not TheDude

class TestSerializer(serializers.ModelSerializer):

    user_test = serializers.SerializerMethodField('get_user_test')

    def get_user_test(self, obj):
        print(type(self.context['request'].user))
1 Answers

It should be possible to use the proxy model by overriding the JWTAuthentication authentication class and setting your proxy user model as the user_model like so:

from rest_framework_simplejwt.authentication import JWTAuthentication


class MyCustomJWTAuthentication(JWTAuthentication):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user_model = TheDude

Say you add this class on myapp/authentication.py, you can then apply this custom authentication class as one of the default authentication classes in your REST_FRAMEWORK settings:

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'myapp.authentication.MyCustomJWTAuthentication',
        ...
        
    )
    ...
}

Or just apply it to certain views you want:

from myapp.authentication import MyCustomJWTAuthentication


class CertainAPIViewThatNeedsTheDude(APIView):
    authentication_classes = (MyCustomJWTAuthentication, )

This should in turn give you a request.user that is a TheDude instance.

Related