我寫了一個自定義身份驗證器,它根據用戶的電子郵件地址而不是用戶名來驗證用戶。這在/admin
打破登錄,因爲它顯然不允許在用戶名字段中使用的電子郵件:管理員登錄名與自定義身份驗證器相關
有沒有一種方法,我可以解決這個問題?
我寫了一個自定義身份驗證器,它根據用戶的電子郵件地址而不是用戶名來驗證用戶。這在/admin
打破登錄,因爲它顯然不允許在用戶名字段中使用的電子郵件:管理員登錄名與自定義身份驗證器相關
有沒有一種方法,我可以解決這個問題?
這是從管理應用程序的相關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表單進行身份驗證?這完全基於使用auth
contrib應用程序中內置的login
和authenticate
方法。這意味着沒有真正有機會改變形式。相反,您必須確保您的自定義身份驗證器已註冊爲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 %}
我假設你已經有了一個可以進行身份驗證的視圖,所以直接發佈到該視圖,並對主管理站點執行成功重定向。