ユーザ登録後のメール送信までの機能が実装できたので,ここではメールリンクのクリックでユーザアカウントが有効化される機能を実装しよう.
このためには views.py を編集します.
users/views.py
def creation_confirm(request, uidb64, token):
def get_user(uidb64, request):
try:
# urlsafe_base64_decode() decodes to bytestring
uid = urlsafe_base64_decode(uidb64).decode()
# messages.success(request, f'uidb64 = {uidb64} に対応する uid は {uid} です')
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist, ValidationError):
user = None
return user
user = get_user(uidb64, request)
if user is not None:
if default_token_generator.check_token(user, token):
if user.is_active == True:
messages.success(request, f'すでに検証できています.ログインしてください.')
return HttpResponseRedirect("/")
user.is_active = True
user.save()
messages.success(request, f'メールを検証ができたので,ユーザ登録を完了しました.')
return HttpResponseRedirect("/")
else:
messages.success(request, f'不正なリンクです.トークンが異なります.')
return HttpResponseRedirect("/")
messages.success(request, f'不正なリンクです.ユーザが存在しません.')
return HttpResponseRedirect("/")
ユーザ登録直後のデータベースを確認します.ユーザ user_e のis_active
が 0 になっている(つまりまだ無効状態である)ことが確認できます.
sqlite> select id, username, is_active, email from users_user; ⏎ id|username|is_active|email 1|user_a|1|a@sample.com 2|user_b|1|b@sample.com 3|user_c|1|c@sample.com 4|root|1|root@example.com 5|user_f|0|f@sample.com 6|user_e|0|e@sample.com sqlite>
ユーザ user_e の(実際は受信可能な)メールアドレスに送信された電子メールのリンクをクリックしてアカウントを有効化します.
データベースを確認すると is_active
が 1 になり,アカウントが有効化されていることがわかりました.
sqlite> select id, username, is_active, email from users_user; ⏎ id|username|is_active|email 1|user_a|1|a@sample.com 2|user_b|1|b@sample.com 3|user_c|1|c@sample.com 4|root|1|root@example.com 5|user_f|0|f@sample.com 6|user_e|1|e@sample.com sqlite>
同じリンクをもう一度開いた場合は,「すでに検証できています」というメッセージが表示されます.
なお,ユーザに送信されるリンクは【/users/create/[ユーザID]/[有効期限]-[ハッシュ]/】の形式になっています.詳細は Django contrib の auth にある tokens.py のコードを参照してください.
たとえばメールリンクの [ユーザID] に該当する部分の文字列を書き換えてアクセスしても「不正なリンク」と判断されます.
同様に [ハッシュ] に該当する部分の文字列を書き換えてアクセスしても「不正なリンク」と判断されます.
なお,[有効期限] はメール送信から72時間です.次のページでは [有効期限] を変更して動作のテストを行います.