djangodjango-modelsdjango-viewsdjango-forms

authenticate() returns none in django


In django i have created a custom user and custom user manager as below: this is my models.py codes:

class CustomUserManager(BaseUserManager):
    def create_user(self, phone_number, password=None):
        if not phone_number:
            raise ValueError('وارد کردن تلفن همراه ضروری می‌باشد.')
        user = self.model(phone_number=phone_number)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, phone_number, password):
        user = self.model(phone_number=phone_number)
        user.set_password(password)
        user.is_active = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user       


class CustomUser(AbstractBaseUser, PermissionsMixin):
    username = None
    name = models.CharField(max_length=30, blank=True, null=True)
    phone_regex = RegexValidator(regex=r'^09\d{9}$', message="شماره تلفن را به صورت ۰۹********* وارد کنید.")
    phone_number = models.CharField(max_length=11, validators=[phone_regex], unique=True)
    is_staff = models.BooleanField(default=False)

    USERNAME_FIELD = 'phone_number'

    objects = CustomUserManager()


    def __str__(self):
        return self.phone_number

this is my forms.py codes:

class UserSignupForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(UserSignupForm, self).__init__(*args, **kwargs)
        self.fields['phone_number'].label = "شماره تلفن"
        self.fields['phone_number'].widget.attrs['class'] = 'form-control input-bg-white l-field'
        self.fields['password'].label = "رمز عبور"
        self.fields['password'].widget.attrs['class'] = 'form-control input-bg-white l-field'
        self.fields['password'].widget.attrs['id'] = 'login-signup-pass'


    def clean_phone_number(self):
        phone_number = self.cleaned_data['phone_number']
        if CustomUser.objects.filter(phone_number=phone_number).exists():
            raise forms.ValidationError("این شماره تلفن قبلا در سایت ثبت شده است.", code="already-exist")
    
        return phone_number

    phone_number = forms.CharField(
        widget=forms.TextInput(attrs={'placeholder': "09123456789"}),
        validators=[RegexValidator(r'^09\d{9}$', message="شماره تلفن وارد شده معتبر نمی‌باشد.")]
    )
    password = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = CustomUser
        fields = ['phone_number', 'password']

and this is my views.py codes:

if request.method == 'POST':
        user_signup_form = UserSignupForm(request.POST)
        repairman_signup_form = RepairmanSignupForm(request.POST)
        if user_signup_form.is_valid() and repairman_signup_form.is_valid():
            form_data = user_signup_form.cleaned_data
            repairman = CustomUser(phone_number=form_data['phone_number'], password=form_data['password'])
            repairman.save()
            repairman.set_password(repairman.password)

            repairman_profile = repairman_signup_form.save(commit=False)

            # Set One to One relationship between UserForm and UserProfileInfoForm
            repairman_profile.user = repairman
            if 'profile_photo' in request.FILES:
                repairman_profile.profile_photo = request.FILES['profile_photo']

            repairman_profile.save()
            phone_number=request.POST['phone_number']
            password=request.POST['password']
            print(phone_number, password)
            new_repairman = authenticate(phone_number=phone_number, password=password)
            print(new_repairman)
            if new_repairman:
                login(request, new_repairman)
            # registered = True
            return redirect('/profile')

now when i want to authenticate the user after signup, the authenticate() returns None. what is the problem?

the user information are correct but authenticate() still not working and it returns None after user signup everytime. i'll be glad to help me. thanks


Solution

  • You are storing the CustomUser with password field in plain text to the database. authenticate() invokes the authenticate() method on the currently configured Auth Backend. Each of these Backends invokes check_password() so ultimately authenticate() will be checking password against a stored password cipher. Your stored passwords are expected to be ciphered when they will be checked but they aren’t. Your stored passwords are in plain text. You can check the database and see for yourself.

    The reason for this is:

    repairman = CustomUser(phone_number=form_data['phone_number'], password=form_data['password'])
    repairman.save()
    repairman.set_password(repairman.password)

    You saved the CustomUser to the database without first setting the password to a cipher. Setting it after without saving to database again to override the first save is as good as not doing anything.

    That which I will recommend is:

    repairman = CustomUser(phone_number=form_data['phone_number'], password=form_data['password'])
    repairman.set_password(repairman.password)
    repairman.save()

    Set to cipher then save.