管理员登录已使用自定义身份验证器

时间:2011-11-29 21:18:53

标签: django django-admin

我编写了一个自定义身份验证器,根据用户的电子邮件地址而不是用户名来验证用户身份。这已经破坏了/admin处的登录信息,因为它显然不允许在用户名字段中使用电子邮件:

enter image description here

有没有办法解决这个问题?

1 个答案:

答案 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)

了解它如何尝试使用usernamepassword的POST数据字段进行身份验证?另请注意,他们如何不使用django表单进行身份验证?这完全基于使用login contrib app的内置authenticateauth方法。这意味着没有机会改变表格。相反,您必须确保自定义身份验证器已注册为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 %}

我假设您已经拥有了一个进行身份验证的视图,因此请直接发布到该视图,并将成功重定向到主管理站点。