use*_*276 25 python django django-authentication django-login
我正在尝试创建一个auth后端,以允许我的用户使用他们的电子邮件地址或Django 1.6中的用户名使用自定义用户模型登录.当我使用用户名登录时后端工作,但由于某种原因没有电子邮件.有什么我忘了做的事吗?
from django.conf import settings
from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(object):
"""
This is a ModelBacked that allows authentication with either a username or an email address.
"""
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
except User.DoesNotExist:
return None
def get_user(self, username):
try:
return User.objects.get(pk=username)
except User.DoesNotExist:
return None
Run Code Online (Sandbox Code Playgroud)
编辑:建议我从ModelBackend继承并在我的设置中安装它在我的设置中我有这个AUTHENTICATION_BACKENDS =('users.backends','django.contrib.auth.backends.ModelBackend',)我已经将后端更改为这个:
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend
class EmailOrUsernameModelBackend(ModelBackend):
"""
This is a ModelBacked that allows authentication with either a username or an email address.
"""
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
except User.DoesNotExist:
return None
def get_user(self, username):
try:
return User.objects.get(pk=username)
except User.DoesNotExist:
return None
Run Code Online (Sandbox Code Playgroud)
现在我收到一个Module "users" does not define a "backends" attribute/class错误.
1bi*_*fMe 20
又一个解决方案:
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
class EmailOrUsernameModelBackend(ModelBackend):
"""
Authentication backend which allows users to authenticate using either their
username or email address
Source: https://stackoverflow.com/a/35836674/59984
"""
def authenticate(self, request, username=None, password=None, **kwargs):
# n.b. Django <2.1 does not pass the `request`
user_model = get_user_model()
if username is None:
username = kwargs.get(user_model.USERNAME_FIELD)
# The `username` field is allows to contain `@` characters so
# technically a given email address could be present in either field,
# possibly even for different users, so we'll query for all matching
# records and test each one.
users = user_model._default_manager.filter(
Q(**{user_model.USERNAME_FIELD: username}) | Q(email__iexact=username)
)
# Test whether any matched user has the provided password:
for user in users:
if user.check_password(password):
return user
if not users:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (see
# https://code.djangoproject.com/ticket/20760)
user_model().set_password(password)
Run Code Online (Sandbox Code Playgroud)
修正:
@用户名字段中不禁止,因此除非自定义用户模型禁止使用@符号,否则不能用于区分用户名和电子邮件.MultipleObjectsReturned异常UserModel._default_manager.get(Q(username__iexact=username) | Q(email__iexact=username)).except:通常是不好的做法缺点 - 如果有两个用户,使用相同的电子邮件,一个在用户名中,另一个在电子邮件中,并且他们有相同的密码,那么它很容易验证第一个匹配.我猜这种可能性很小.
另请注意:任何方法都应email在User模型中强制使用唯一字段,因为默认的User模型未定义唯一的电子邮件,这会导致在使用情况下出现未处理的异常User.objects.get(email__iexact="..."),或者验证第一个匹配项.在任何情况下,使用电子邮件登录都假定电子邮件是唯一的.
use*_*276 11
按照上面给出的建议并改变后AUTHENTICATION_BACKENDS = ['yourapp.yourfile.EmailOrUsernameModelBackend']我得到了错误Manager isn't available; User has been swapped for 'users.User'.这是因为我使用默认的User模型而不是我自己的自定义模型.这是工作代码.
from django.conf import settings
from django.contrib.auth import get_user_model
class EmailOrUsernameModelBackend(object):
"""
This is a ModelBacked that allows authentication with either a username or an email address.
"""
def authenticate(self, username=None, password=None):
if '@' in username:
kwargs = {'email': username}
else:
kwargs = {'username': username}
try:
user = get_user_model().objects.get(**kwargs)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, username):
try:
return get_user_model().objects.get(pk=username)
except get_user_model().DoesNotExist:
return None
Run Code Online (Sandbox Code Playgroud)
我以为我会把更简单的方法吸引给遇到此问题的其他人:
# -*- coding: utf-8 -*-
from django.contrib.auth import backends, get_user_model
from django.db.models import Q
class ModelBackend(backends.ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(Q(username__iexact=username) | Q(email__iexact=username))
if user.check_password(password):
return user
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (#20760).
UserModel().set_password(password)
Run Code Online (Sandbox Code Playgroud)
注意:
USERNAME_FIELD,尽管您可以轻松地将其重新添加__iexact以使其不区分大小写)小智 6
我知道这个问题已经得到解答,但是我找到了一种真正巧妙的方法来使用 Django 身份验证视图通过电子邮件和用户名实现登录。我没有看到有人使用这种方法,所以我想为了简单起见我会分享它。
from django.contrib.auth.models import User
class EmailAuthBackend():
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(email=username)
if user.check_password(raw_password=password):
return user
return None
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
Run Code Online (Sandbox Code Playgroud)
然后在你的settings.py中添加这个
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'myapp.authentication.EmailAuthBackend',
)
Run Code Online (Sandbox Code Playgroud)
我通过两个简单的步骤为此编写了代码:
VIEWS.py if request.method == 'POST':
userinput = request.POST['username']
try:
username = userbase.objects.get(email=userinput).username
except userbase.DoesNotExist:
username = request.POST['username']
password = request.POST['password']
Run Code Online (Sandbox Code Playgroud)
INDEX.html
我创建了 2 个输入字段,第一个用于用户名/电子邮件。我接受给出的任何输入,并尝试在数据库的电子邮件列中搜索相同的数据,如果匹配,我返回用户名,然后尝试进行身份验证,如果不匹配,我直接使用输入作为用户名。
我正在使用 Django 2.2
小智 5
您可以简单地使用 Try 块来执行此操作..使用:
email = request.POST['username']
raw_password = request.POST['password']
try:
account = authenticate(username=MyUserAccount.objects.get(email=email).username,password=raw_password)
if account is not None:
login(request, account)
return redirect('home')
except:
account = authenticate(username=email, password=raw_password)
if account is not None:
login(request, account)
return redirect('home')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14631 次 |
| 最近记录: |