Search code examples
pythondjangodjango-modelsdjango-formsdjango-authentication

"User already exist" Custom Django Authentication Backend


I'm coding a custom django authentication, the code works fine for user creation but when I try to login, it is like if I were signing up again, so there is no way of accessing my user account because every time I try to login, I get an error because a user with that credentials already exist (I'm that user).

The output is: <ul class="errorlist"><li>address<ul class="errorlist"><li>User with this Address already exists.</li></ul></li></ul>

Models.py:

class AppUser(AbstractUser):
    username = models.TextField(unique=True)
    address = models.CharField(max_length=34, unique=True)
    key = models.CharField(max_length=34)
    
    def __str__(self):
        return self.username

Forms.py:

class NewUserForm(forms.ModelForm): 
    class Meta:
        model = AppUser
        fields = ("username", "address", "key")

    def save(self, commit=True):
        user = super(NewUserForm, self).save(commit=False)
        user.address = self.cleaned_data["address"]
        user.key = self.cleaned_data['key']
        if commit:
            user.save()
        return user

class LoginUserForm(forms.ModelForm): 
    class Meta:
        model = AppUser
        fields = ("address", "key")

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

Backends.py:

class AppUserBackend(ModelBackend):

    def authenticate(self, request, **kwargs):
        address = kwargs['address']
        key = kwargs['key']
        try:
            customer = AppUser.objects.get(address=address)
            
            if customer.key == key:
                return customer.user
            else:
                print("Error")
        except AppUser.DoesNotExist:
            pass

Views.py:

def login_request(request):
    if request.method == 'POST':
        form = LoginUserForm(request=request, data=request.POST) 
        if form.is_valid():
            address = form.cleaned_data.get('address')
            key = form.cleaned_data.get('key')
            user = authenticate(request=request, address=address, key=key)
            if user is not None:
                login(request, user, backend='main.backends.AppUserBackend')
                return redirect("main:home")
            else:
                print("User is none")
        else:
            print("Not valid")

    form = LoginUserForm()
    return render(request = request,
                    template_name = "main/login.html",
                    context={"form":form}
                    )

def register(request):
    if request.method == "POST":
        form = NewUserForm(request.POST)
        if form.is_valid():
            user = form.save()

            login(request, user, backend='main.backends.AppUserBackend')
            return redirect("main:index")

            return render(request = request,
                        template_name = "main/register.html",
                        context={"form":form})
            
    form = NewUserForm
    return render(request = request,
                  template_name = "main/register.html",
                  context={"form":form}
                  )

When I run the code, I can create a user without problems and the user is stored in the database but when I try to login, it's like if i were creating an user again. I know I'm missing but don't know what.


Solution

  • I solved the problem by changing forms.py, from:

    class LoginUserForm(forms.ModelForm): 
        class Meta:
            model = AppUser
            fields = ("address", "key")
    
        def __init__(self, request=None, *args, **kwargs):
            self.request = request
            super().__init__(*args, **kwargs)
    

    to:

    class LoginUserForm(forms.Form): 
        address = forms.CharField(label='address', max_length=100)
        private_key = forms.CharField(label='private_key', max_length=100)
    
        def __init__(self, request=None, *args, **kwargs):
            self.request = request
            super().__init__(*args, **kwargs)
    

    So the main problem was that I was calling LoginUserForm which inherited from forms.ModelForm, a class that has a save() method, so I was saving/creating the user again instead of authenticating.