我编写了一个自定义身份验证器,根据用户的电子邮件地址而不是用户名来验证用户身份。这已经破坏了/admin
处的登录信息,因为它显然不允许在用户名字段中使用电子邮件:
有没有办法解决这个问题?
答案 0 :(得分:2)
以下是管理员应用中的相关login
方法(不重要的细节省略):
def login(self, request):
from django.contrib.auth.models import User
# Check the password.
username = request.POST.get('username', None)
password = request.POST.get('password', None)
user = authenticate(username=username, password=password)
if user is None:
message = ERROR_MESSAGE
if username is not None and u'@' in username:
# Mistakenly entered e-mail address instead of username? Look it up.
try:
user = User.objects.get(email=username)
except (User.DoesNotExist, User.MultipleObjectsReturned):
message = _("Usernames cannot contain the '@' character.")
else:
if user.check_password(password):
message = _("Your e-mail address is not your username."
" Try '%s' instead.") % user.username
else:
message = _("Usernames cannot contain the '@' character.")
return self.display_login_form(request, message)
# The user data is correct; log in the user in and continue.
else:
if user.is_active and user.is_staff:
login(request, user)
return http.HttpResponseRedirect(request.get_full_path())
else:
return self.display_login_form(request, ERROR_MESSAGE)
login = never_cache(login)
了解它如何尝试使用username
和password
的POST数据字段进行身份验证?另请注意,他们如何不使用django表单进行身份验证?这完全基于使用login
contrib app的内置authenticate
和auth
方法。这意味着没有机会改变表格。相反,您必须确保自定义身份验证器已注册为authentication backend。
AUTHENTICATION_BACKENDS = ('mysite.backends.EmailBackend',)
由于内置管理员登录方法仅在AUTH_BACKEND未返回用户时检查是否存在电子邮件地址,这意味着您可以自由使用现有表单中的电子邮件地址。这应该有效,但如果没有(并且你已经设置了Auth后端),下面是另一种方法。
因此,您可以做的事情是覆盖管理员登录模板,并发布到您自己的自定义登录视图,该视图使用您自己的身份验证器。
致override the default login page:
cp [src dir]/django/django/contrib/admin/templates/admin/login.html [project root]/templates/admin/login.html
接下来,您将要删除现有的表单操作,并将其指向您自己的视图:
<form action="/custom/login" method="post" id="login-form">{% csrf_token %}
我假设您已经拥有了一个进行身份验证的视图,因此请直接发布到该视图,并将成功重定向到主管理站点。