3

I'm working on creating a custom login API with phon number using django-rest-auth package. I am just using rest_auth.views.LoginView in my code to generate token for token authentication.

this is my serializer:

class LoginUserSerializer(serializers.Serializer):
    phone = serializers.CharField()
    password = serializers.CharField(
        style={'input_type': 'password'}, trim_whitespace=False)

    def validate(self, attrs):
        phone = attrs.get('phone')
        password = attrs.get('password')

        if phone and password:
            if User.objects.filter(phone=phone).exists():
                user = authenticate(request=self.context.get('request'),
                                    phone=phone, password=password)

            else:
                msg = {'detail': 'Phone number is not registered.',
                       'register': False}
                raise serializers.ValidationError(msg)

            if not user:
                msg = {
                    'detail': 'Unable to log in with provided credentials.', 'register': True}
                raise serializers.ValidationError(msg, code='authorization')

        else:
            msg = 'Must include "username" and "password".'
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        return attrs

and this is my view:

 from rest_auth.views import LoginView as RestLoginView

class Login(RestLoginView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request, *args, **kwargs):
        serializer = LoginUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        return super().post(request, format=None)

when I run the server I have this page and I don't want to have username and email fields. instead of these, I want phone number. how do I can fix this????

enter image description here

Nesrine Hadj Khelil
  • 278
  • 1
  • 4
  • 13

2 Answers2

3

in the settings.py i forgot to add:

REST_AUTH_SERIALIZERS = {
    'LOGIN_SERIALIZER': 'Accounts.serializers.LoginUserSerializer',
}
0

this way it works too.. i use phone_number from my CustomUserModel and otp code to login;

this is my serializer:

class UserLoginSerializer(serializers.Serializer):
    phone_number = serializers.CharField(max_length=11, required=True)
    password = serializers.CharField(required=False, allow_null=True, write_only=True)
    otp = serializers.CharField(required=False, allow_null=True)

    def validate(self, attrs):
        phone_number = attrs.get('phone_number')
        user = User.objects.filter(phone_number=phone_number).exists()
        if user:
            return attrs
        else:
            msg = {
                'detail': 'User does not exists.', 'register': True}
            raise serializers.ValidationError(msg, code='authorization')


class UserLogoutSerializer(serializers.Serializer):
    phone_number = serializers.CharField(max_length=11, required=True)

    def validate(self, attrs):
        phone_number = attrs.get('phone_number')
        user = User.objects.filter(phone_number=phone_number).exists()
        if user:
            return attrs
        else:
            msg = {
                'detail': 'User does not exists.', 'register': True}
            raise serializers.ValidationError(msg, code='authorization')

this is my view:

class UserLoginView(APIView):
    def post(self, request):
        ser_data =UserLoginSerializer(data=request.POST)
        if ser_data.is_valid():
            data = ser_data.validated_data
            user = User.objects.get(phone_number=data['phone_number'])
            if user:
                if user.check_password(data['password']) or (data['otp'] == user.otp):
                    login(request, user)
                    user.otp = None
                    user.save()
                    return Response(ser_data.data, status=status.HTTP_200_OK)
                return Response({'detail': 'inter password or otp'})
            return Response({'detail': 'user does not exists'})
        return Response(ser_data.errors, status=status.HTTP_400_BAD_REQUEST)

class UserLogoutView(APIView):

    def post(self, request):
        ser_data =UserLogoutSerializer(data=request.POST)
        if ser_data.is_valid():
            data = ser_data.validated_data
            user = User.objects.get(phone_number=data['phone_number'])
            if user:
                logout(request)
                return Response(ser_data.data, status=status.HTTP_200_OK)
            return Response({'detail': 'user does not exists'})
        return Response(ser_data.errors, status=status.HTTP_400_BAD_REQUEST)

if you got csrf_token error , reference to this page:https://stackoverflow.com/a/52782448/18089125