1

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 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

9 Comments

I'm using djangorestframework-jwt rather than djangorestframework-simplejwt but I'll look into moving across. I'll see if I can modify your answer into the different library.
I see. That package seems to be unmaintained, and uses rather old django versions. Anyway you can do the same idea with authenticate_credentials
I think I'll see about transferring it to a maintained package. I inherited this app unfortunately.
I've moved auth library and implemented this code however I'm still getting User object in my serialisers when I do self.context['request'].user
Can you update your question with latest changes? Also with the current settings
|

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.