[英]How to authenticate user via REST using email and password with Django Rest Framework
[英]Authenticate user using email and password
我有一个表单,只允许用户通过用户名登录。 我决定只允许用户通过电子邮件而不是用户名登录。
首先,这不是与通过电子邮件进行日志记录有关的任何问题的重复,因为在我的场景中,我在forms.py
验证并验证用户,然后他继续在视图中进行最终登录,这样我就有机会提出错误错误的登录密码等
我面临的问题是我修改了我的forms.py
以引发错误,如果电子邮件不存在,但它不会让用户通过他的电子邮件登录。
def LoginRequest(request):
form = LoginForm(request.POST or None)
if request.POST and form.is_valid():
user = form.login(request)
if user:
login(request, user)
return HttpResponseRedirect(reverse('Hello'))
return render(request, 'login.html',{'form': form})
这是我的原始代码,只允许用户通过用户名登录
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(
widget=forms.PasswordInput(render_value=False)
)
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if not user or not user.is_active:
raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
return self.cleaned_data
def login(self, request):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
user = authenticate(username=username, password=password)
return user
这是我修改过的代码,只允许用户通过电子邮件登录。 我想了很多我会怎么做但这是我提出的最好的主意。 对不起,这有点令人困惑。 问题是,它不会让用户登录。 我不明白为什么。
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(
widget=forms.PasswordInput(render_value=False)
)
def clean(self):
user = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if User.objects.filter(email=user).exists():
password = self.cleaned_data.get('password')
user = authenticate(username=user.username, password=password)
if not user or not user.is_active:
raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
return self.cleaned_data
def login(self, request):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
user = authenticate(username=username, password=password)
return user
有人可以帮帮我吗?
正如dougis
指出您正在尝试使用电子邮件对用户进行authenticate
验证,但authenticate
功能会根据用户名和密码对用户进行身份验证。 所以这是使用电子邮件验证用户的技巧(完整的工作表单):
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User
from django import forms
from django.contrib.auth import authenticate
class LoginForm(forms.Form):
email = forms.CharField()
password = forms.CharField(
widget=forms.PasswordInput(render_value=False)
)
def clean(self):
user = self.authenticate_via_email()
if not user:
raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
else:
self.user = user
return self.cleaned_data
def authenticate_user(self):
return authenticate(
username=self.user.username,
password=self.cleaned_data['password'])
def authenticate_via_email(self):
"""
Authenticate user using email.
Returns user object if authenticated else None
"""
email = self.cleaned_data['email']
if email:
try:
user = User.objects.get(email__iexact=email)
if user.check_password(self.cleaned_data['password']):
return user
except ObjectDoesNotExist:
pass
return None
views.py
def LoginRequest(request):
form = LoginForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
user = form.authenticate_user()
login(request, user)
return HttpResponseRedirect(reverse('Hello'))
return render(request, 'login.html',{'form': form})
您还可以编写自定义后端:
# yourapp.backends.py
from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(object):
""" Authenticate user by username or email """
def authenticate(self, username=None, password=None):
if '@' in username:
kwargs = {'email': username}
else:
kwargs = {'username': username}
try:
user = User.objects.get(**kwargs)
if user.check_password(password):
return user
else:
return None
except User.DoesNotExist:
return None
def get_user(self, user_id=None):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
现在将您的后端添加到settings.py:
AUTHENTICATION_BACKENDS = (
'yourapp.backends.EmailOrUsernameModelBackend',
'django.contrib.auth.backends.ModelBackend',
)
看起来你正在测试2个不同的领域。 您根据电子邮件查找用户
if User.objects.filter(email=user).exists():
但然后验证用户名
user = authenticate(username=user, password=password)
如果您使用的是电子邮件地址,则应该使用auth行
user = authenticate(email=user, password=password)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.