以前我一直在研究如何使用电子邮件地址而不是用户名注册的几种解决方案。我发现的所有资源都集中在创建自定义后端和滚动注册页面上。虽然这对我有用,但我找不到解释如何处理登录屏幕的单一解决方案。
首先,我使用电子邮件授权的方法
注册:我获取电子邮件地址并将其创建为用户名的哈希值并存储它。
登录:我再次获取电子邮件地址并创建它的哈希并尝试找到具有相同哈希的用户名。
它是如何在代码中完成的:
在设置中:
AUTHENTICATION_BACKENDS = ('MyApp.auth_backends.CustomUserModelBackend',)
CUSTOM_USER_MODEL = 'MyApp.CustomUser'
在模型.py
class CustomUser(User):
timezone = models.CharField(max_length=50, default='Europe/London')
objects = UserManager()
我已经定制了这样的注册:
视图.py
def register_page(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = CustomUser.objects.create_user(
username=md5(form.cleaned_data['email']).digest().encode('base64')[:-1],
password=form.cleaned_data['password2'],
email=form.cleaned_data['email']
)
return HttpResponseRedirect('/register/success/')
else:
form = RegistrationForm()
variables = RequestContext(request, {'form':form})
return render_to_response('registration/register.html', variables)
在auth_backends.CustomUserModelBackend 中:
计算给定电子邮件地址的哈希值以找到相关的用户名。
class CustomUserModelBackend(ModelBackend):
def authenticate(self, username=None, password=None):
try:
# The parameter Username is here really just the email address, I get
# the hash for the email parameter and try to find the user.
hash_user = md5(username).digest().encode('base64')[:-1],
user = self.user_class.objects.get(username=hash_user)
if user.check_password(password):
return user
except self.user_class.DoesNotExist:
return None
def get_user(self, user_id):
try:
return self.user_class.objects.get(pk=user_id)
except self.user_class.DoesNotExist:
return None
@property
def user_class(self):
if not hasattr(self, '_user_class'):
self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
if not self._user_class:
raise ImproperlyConfigured('Could not get custom user model')
return self._user_class
现在我被登录屏幕困住了。
我已经这样做了,但是我被重定向回登录屏幕而没有显示任何错误。
网址.py
(r'^login/$', 'django.contrib.auth.views.login'),
注册/login.html
{% extends "base.html" %}
{% block title %}user login{% endblock %}
{% block head %}User login{% endblock %}
{% block content %}{% if form.errors %}
<p>Your email and password didn't match</p>
{% endif %}
<form action="." method="post">
<p>
<label for="id_username">Email:</label>{{ form.username }}
</p>
<p>
<label for="id_password">Password:</label>{{ form.password }}
</p>
{% csrf_token %}
<input type="hidden" name="next" value="/" />
<input type="submit" value="login" />
</form>
{% endblock %}
我知道该解决方案已经存在问题,因为我需要“用户名”而不是字符字段的电子邮件输入。
1)我该怎么做才能覆盖字段类型?
2)我仍然无法登录,它说用户名与密码不匹配。
我在 Authenticate 中对其进行了调试,但没有找到用户
hash_user = md5(username).digest().encode('base64')[:-1],
user = self.user_class.objects.get(username=hash_user)
同一个电子邮件地址的哈希值不总是相同的吗?我会错过什么?
更新:
我可以清楚地看到哈希码作为用户名保存在数据库中,我可以看到在 Authenticateuser = self.user_class.objects.get(username=hash_user)
中哈希码与数据库中的值相同。但是它仍然没有检索到用户。为什么?
更新 2:
我发现了问题。我在那里错误地使用了一个逗号,这将哈希变成了一个元组。哦亲爱的
这是正确的并且有效:
hash_user = md5(username).digest().encode('base64')[:-1]
user = self.user_class.objects.get(username=hash_user)
我们现在在这里有了完整的解决方案。就一件事。
有人能帮我解决 1) 吗?请问如何覆盖用户名字符字段?