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.
CodePudding user response:
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()
CodePudding user response:
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