Python – Get the user role and add it to the jwt payload

Get the user role and add it to the jwt payload… here is a solution to the problem.

Get the user role and add it to the jwt payload

I

have a user login serializer like this I want to add user roles to my JWT payload when the user is authenticated How do I access user information, such as the “is_stuff” field in my validation function? The user object contains <QuerySet [<User: admin>]>

class UserLoginSerializer(ModelSerializer):
    token = CharField(allow_blank=True, read_only=True)
    username = CharField(required=False, allow_blank=True)
    email = EmailField(label='email address', required=False, allow_blank=True)

class Meta:
        model = User
        fields = [
            'username',
            'email',
            'password',
            'token',
            'is_staff',
        ]
        extra_kwargs = {
            "password": {
                "write_only": True
            }
        }

def validate(self, data):
        user_obj = None
        email = data.get('email', None)
        username = data.get('username', None)
        password = data.get('password')
        if not email and not username:
            raise ValidationError("email or username is required!")
        if '@' in username:
            email = username
        user = User.objects.filter(
            Q(email=email) |
            Q(username=username)
        ).distinct()

# user = user.exclude(email__isnull=True).exclude(email__iexact='')
        if user.exists() and user.count() == 1:
            user_obj = user.first()
        else:
            raise ValidationError("this username/email is not valid")
        if user_obj:
            if not user_obj.check_password(password):
                raise ValidationError("password is incorrect")

payload = jwt_payload_handler(user_obj)
        payload["role"] = ???
        data['token'] = jwt_encode_handler(payload)
        return data

View :

class UserLoginApiView(APIView):
    permission_classes = [AllowAny]
    serializer_class = UserLoginSerializer

def post(self, request, *args, **kwargs):
        data = request.data
        serializer = UserLoginSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            new_data = serializer.data
            return Response(new_data, status=HTTP_200_OK)

return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

Solution

If you are using rest_framework_jwt just define:

JWT_AUTH = {
    ...
    'JWT_PAYLOAD_HANDLER': 'project.jwt.jwt_payload_handler',
    ...
}

And you can define your own function (or how you call it) in this file, project.jwt

from django.conf import settings
from rest_framework_jwt import utils

def jwt_payload_handler(user):
    payload = utils.jwt_payload_handler(user)
    payload['is_staff'] = user.is_staff
    payload['is_superuser'] = user.is_superuser
    ....
    return payload

Related Problems and Solutions