Authentication with three fields in django-rest-framework-simple-jwt


I am working on custom authentication in DRF. User should send 3 fields (phone, email, password).

I was following this answer Adding custom user authentication to django-rest-framework-simple-jwt
(I was overriding TokenObtainPairSerializer and TokenObtainPairView)

I was using this source code

Problem: for the request below I received an empty response {} but expected tokens or error message

    "email": "[email protected]",
    "password": "admin123456",
    "phone_number": "123132"

My code:

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    username_field = CustomUser.USERNAME_FIELD

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields[self.username_field] = serializers.CharField()
        self.fields['password'] = PasswordField()
        self.fields['phone_number'] = serializers.CharField() # authentication requires 3 fields

    def validate(self, attrs):
        authenticate_kwargs = {
            self.username_field: attrs[self.username_field],
            'password': attrs['password'],
            'phone_number': attrs['phone_number']
            authenticate_kwargs["request"] = self.context["request"]
        except KeyError:

        self.user = authenticate(**authenticate_kwargs)

        if not api_settings.USER_AUTHENTICATION_RULE(self.user):
            raise exceptions.AuthenticationFailed(

        return {}


Let’s try to login and generate a token manually:

from rest_framework import serializer

class LoginUserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    phone_number = serializers.CharField()
    password = serializers.CharField(write_only=True)

from django.contrib.auth import authenticate

from rest_framework import status, serializers
from rest_framework.response import Response
from rest_framework.views import APIView

from rest_framework_simplejwt.tokens import RefreshToken

class LoginUserApi(APIView):

    def post(self, request):
        serializer = LoginUserSerializer(
        data = serializer.validated_data # Fetch the data form serializer

        user = authenticate(email=data['email'], password=data['password']) # check for email and password
        if not user or user.phone_number != data['phone_number']: # check for phone
            raise serializers.ValidationError({'detail':'Incorrect email, phone, or password'})

        # Generate Token
        refresh = RefreshToken.for_user(user)

        return Response(
                'access': str(refresh.access_token),
                'refresh': str(refresh)
            , status=status.HTTP_200_OK

How to create tokens manually from Simple JWT docs

Answered By – Mohamed Hamza

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published