I want to add user login via One-time Password as well as the usual username/password method in django. In order to do so, either username/password or username/OTP are sent from client to sever and based on the provided pair of fields, I need to return access and refresh token if the user is authenticated. I am using django's simple-jwt. I know that I have to override TokenObtainPairView and TokenObtainSerializer. The problem is, I want to do the field validation part myself.
In my views, I override simple-jwt's default view.
#views.py
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
And I override the serializer like below:
#serializers.py
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
try:
request = self.context["request"]
except KeyError:
pass
try:
request_data = json.loads(request.body)
if("username" in request_data and "password" in request_data):
# default scenario in simple-jwt
pass
elif("username" in request_data and "otp" in request_data):
# validate username/otp manually and return access/token pair if successful
pass
else:
# some fields were missing
raise serializers.ValidationError({"username/otp or username/password" : "These fields are required"})
except:
pass
So, if client passes user credentials in one of the possible forms below, I will be able to authenticate it and return token pair.
{
"username" : "Winston",
"password" : "testpass"
}
or
{
"username" : "Winston",
"otp" : "testotp"
}
The problem is, when I send data in the second form, I get 400 BadRequest:password is required
. How can I customize fields and their validation?