我试图使自定义用户使用电子邮件而不是用户名登录,但验证(电子邮件=电子邮件,密码=密码)返回无,虽然用户存在
class CustomUserManager(UserManager):
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
class User(AbstractUser):
email = models.EmailField(max_length=254, unique=True)
username = None
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager() # use the custom manager
def __str__(self):
return self.email
字符串
网址:Views.py
class SignUp(CreateView):
form_class = SignUpForm
template_name = 'signup.html'
def form_valid(self, form):
email = form.cleaned_data['email']
password1 = make_password(form.cleaned_data['password1'])
password2 = make_password(form.cleaned_data['password2'])
user = User(email=email, password=password1, username=email)
user = user.save()
print("User created!")
user = authenticate(username=email, password=password1)
login(self.request, user)
return redirect('home')
class LoginView(FormView):
template_name = 'login.html'
form_class = LoginForm
def form_valid(self, form):
email = form.cleaned_data['email']
password = make_password(form.cleaned_data['password'])
print(email, password) # for debugging purposes
user = authenticate(username=email, password=password)
print(user) # for debugging purposes
if user is not None:
print('do')
login(self.request, user)
return redirect('home')
else:
messages.info(self.request, 'invalid username or password')
return redirect('login')
型
网址:backends.py
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
class EmailBackend(ModelBackend):
def authenticate(self, request, password=None, email=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=email)
except UserModel.DoesNotExist:
return None
else:
if user.check_password(password):
return user
return None
型
settings.py
AUTH_USER_MODEL = 'accounts.User'
AUTHENTICATION_BACKENDS = [
'accounts.backends.EmailBackend',
型
]
网址:forms.py
from .models import User
from django.contrib.auth.forms import UserCreationForm
from django import forms
class SignUpForm(UserCreationForm):
email = forms.EmailField(widget=forms.EmailInput(
attrs={'class' : 'form-control',
'type' : "text",
'class' : "form-control",
'placeholder': "Email"}))
password1 = forms.CharField(min_length=8, label='Password', widget=forms.PasswordInput(
attrs={'id' : "password-field",
'class' : 'form-control',
'type' : "password",
'class' : "form-control",
'placeholder': "Password",
'toggle' : "#password-field",}))
password2 = forms.CharField(min_length=8, label='Confirm Password',
widget=forms.PasswordInput(
attrs={'id' :"password-field",
'class' : 'form-control',
'type' : "password",
'class' : "form-control",
'placeholder': "Confirm Password",}))
class Meta:
model = User
fields = ('email', 'password1', 'password2')
class LoginForm(forms.Form):
email = forms.CharField(widget=forms.EmailInput(
attrs={'class' : 'form-control',
'type' : "text",
'class' : "form-control",
'placeholder': "Email"}))
password = forms.CharField(min_length=8, label='Password', widget=forms.PasswordInput(
attrs={'id' : "password-field",
'class' : 'form-control',
'type' : "password",
'class' : "form-control",
'placeholder': "Password",
'toggle' : "#password-field",}))
class Meta:
model = User
fields = ('email', 'password',)
型
我想知道为什么user的值是None。我确信电子邮件和密码与数据库匹配。
1条答案
按热度按时间mqkwyuun1#
问题是您对
make_password
和check_password
的使用。LoginView
不应该做make_password
。这是将原始密码转换为加密密码的函数。由于您只想在数据库中存储加密的密码,因此您希望在注册新用户时使用此功能**,而不是在登录用户时使用**。check_password
的函数需要两个必参数。这是您的代码中尚未遇到的错误。您的
LoginView
应该将原始密码传递给您的authenticate
方法(现在您正在传递加密的密码)。然后,在authenticate
方法中,您应该检查原始密码与来自数据库的加密密码。这是您需要传递给check_password
的两个参数。如果您将加密的密码传递给check_password
方法,它将再次加密加密的密码。您将看到check_password("xyz", "xyz")
不是True
。个字符