以前、ユーザー名の代わりに電子メール アドレスで登録する方法をいくつか調査してきました。私が見つけたすべてのソースは、カスタム バックエンドの作成とサインアップ ページのローリングに焦点を当てています。これは私にとってはうまくいきますが、ログイン画面で何をすべきかを説明する単一の解決策を見つけることができませんでした.
まず、メール認証に関する私のアプローチ
登録: メール アドレスを取得し、そのハッシュをユーザー名として作成し、保存します。
ログイン: メールアドレスをもう一度取得してハッシュを作成し、同じハッシュを持つユーザー名を見つけようとします。
コードでの実行方法:
設定で:
AUTHENTICATION_BACKENDS = ('MyApp.auth_backends.CustomUserModelBackend',)
CUSTOM_USER_MODEL = 'MyApp.CustomUser'
models.pyで
class CustomUser(User):
timezone = models.CharField(max_length=50, default='Europe/London')
objects = UserManager()
次のように登録をカスタマイズしました。
View.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
今、ログイン画面で立ち往生しています。
私はこのようにしましたが、エラーが表示されることなくログイン画面にリダイレクトされます。
url.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) まだログインできません。ユーザー名がパスワードと一致しません。
認証でデバッグしましたが、ユーザーが見つかりません
hash_user = md5(username).digest().encode('base64')[:-1],
user = self.user_class.objects.get(username=hash_user)
同じメールアドレスのハッシュはいつも同じではありませんか? 何が欠けている可能性がありますか?
アップデート:
ハッシュ コードがユーザー名としてデータベースに保存されていることがはっきりとわかります。また、Authenticate 内でハッシュ コードがデータベースとuser = self.user_class.objects.get(username=hash_user)
同じ値であることがわかります。ただし、まだユーザーを取得していません。なんで?
更新 2:
問題が見つかりました。誤ってカンマが 1 つあり、それがハッシュをタプルに変えてしまいました。まあ
これは正しく、機能します:
hash_user = md5(username).digest().encode('base64')[:-1]
user = self.user_class.objects.get(username=hash_user)
これで完全なソリューションがここにあります。たったひとつ。
1)で私を助けることができる人はいますか?ユーザー名のcharfieldを上書きするにはどうすればよいですか?