Django: unable to login user with correct email/password

I am very new to Django and this is my first project. I am trying to build a simple login/registration with MySQL as db and a custom user model. The user is successfully signing up but unable to login using correct pw and email.

I tried redoing my signup function and index function (login) and changed username to email in my custom model and index function.

view.py:

from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.shortcuts import render, redirect
from .models import CustomUser
from .forms import CustomUserCreationForm, EmailAuthenticationForm
from django.contrib.auth.forms import AuthenticationForm
from .backends import EmailBackend


# sign up
def signup(request):
    if request.user.is_authenticated:
        # if user is already logged in, redirect to the appropriate page
        return redirect('/home')
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            user = form.save(commit=True)
            # Hash the password
            user.set_password(user.password)
            user.save()
    else:
        form = CustomUserCreationForm()
    return render(request, 'signup.html', {'form': form})



# login  
def index(request):
    if request.method == 'POST':
        form = EmailAuthenticationForm(data=request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = EmailBackend().authenticate(request, email=email, password=password)
            if user is not None:
                login(request, user)
                return redirect('home')
            else:
                return redirect('error')
    else:
        form = EmailAuthenticationForm()
    return render(request, 'index.html', {'form': form})

forms.py:

 from django import forms
 from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
 from .models import CustomUser


# custom sign up form
class CustomUserCreationForm(UserCreationForm):
    first_name = forms.CharField(widget=forms.TextInput(attrs={'autofocus':'autofocus'}))
    email = forms.EmailField()
    class Meta(UserCreationForm):
        editable = True
        model = CustomUser
        fields = ('first_name', 'last_name', 'email')

# custom login form:
class EmailAuthenticationForm(AuthenticationForm):
    username = forms.EmailField(widget=forms.EmailInput(attrs={'autofocus': True}))
    # clean username function to make sure the username is an email
    def clean_username(self):
        username = self.cleaned_data.get('username')
        try:
            CustomUser.objects.get(email=username)
            return username
        except CustomUser.DoesNotExist:

models.py:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser

# custom user model to include extra fields:
class CustomUser(AbstractBaseUser):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField(unique=True, max_length=255)
    is_staff = models.BooleanField(default=False)
    # keeps track of whether the account was confirmed or not thgough email confirmation
    is_active = models.BooleanField(default=True)
    REQUIRED_FIELDS = ['first_name', 'last_name']
    USERNAME_FIELD = 'email'
    # changed the default manager to the custom manager for login
    @classmethod
    def get__by_natural_key(cls, email):
        return cls.objects.get(email=email)

backends.py:

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User
from .models import CustomUser

class EmailBackend(BaseBackend):
    def authenticate(self, request, email=None, password=None, **kwargs):
        try:
            user = CustomUser.objects.get(email=email)
        except CustomUser.DoesNotExist:
            return None
        if user.check_password(password):
            return user
    def get_user(self, user_id):
        try:
            return CustomUser.objects.get(pk=user_id)
        except CustomUser.DoesNotExist:
            return None

All the similar posts I found were about staff or admin users.

The UserCreationForm already hashes the function, you are here hashing it a second time. You thus sign up with:

def signup(request):
    if request.user.is_authenticated:
        # if user is already logged in, redirect to the appropriate page
        return redirect('/home')
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            return redirect('name-of-some-view')
    else:
        form = CustomUserCreationForm()

In your EmailBackend.authenticate function, I see that you are loading a user and checking their password, but I don't see a login() function before you return user. Might this be the missing piece?

Here is the Django docs explaining the user login process for a django.contrib.auth.models.User object: https://docs.djangoproject.com/en/4.1/topics/auth/default/#how-to-log-a-user-in

Back to Top