Djangoでユーザー登録をメール承認(認証)付きにするのは多少の設定が必要ですが、Djangoが提供する機能を活用すれば、それほど大変ではありません。以下に、ステップごとに分解して説明します。
1. メール認証付きユーザー登録の流れ
- ユーザーがフォームで登録
- 仮登録の状態でユーザーをデータベースに保存。
- メールを送信
- ユーザーの入力したメールアドレス宛に認証用のリンクを送信。
- ユーザーがリンクをクリック
- 認証リンクにアクセスした際、アカウントを有効化。
- 有効化されたアカウントでログイン可能に
2. 実装手順
2.1 仮登録用のモデルフィールドを追加
デフォルトのユーザーモデルには「有効/無効」を管理するフィールドがないため、is_active
フィールドを利用します。
- 新規登録時にデフォルトで
is_active=False
に設定し、メール認証後にTrue
に変更します。
forms.py
(変更なし)
上記で作成した CustomUserCreationForm
をそのまま使用します。
2.2 認証トークン生成と検証
Djangoの signing
モジュールを利用して、メール認証用のトークンを生成します。
認証トークン生成ヘルパー
utils.py
を新規作成します。
pythonfrom django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.contrib.auth.models import User
# トークン生成
def generate_email_verification_token(user):
return default_token_generator.make_token(user)
# トークンの検証
def verify_email_token(uidb64, token):
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
return None
if default_token_generator.check_token(user, token):
return user
return None
2.3 メール送信ビューの作成
Djangoの send_mail
を使ってメールを送信します。
views.py
pythonfrom django.shortcuts import render, redirect
from django.contrib.auth import login
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from django.contrib.sites.shortcuts import get_current_site
from .forms import CustomUserCreationForm
from .utils import generate_email_verification_token
def register(request):
if request.method == "POST":
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # 仮登録
user.save()
# メール送信
current_site = get_current_site(request)
subject = "Activate Your Account"
message = render_to_string("email_verification.html", {
"user": user,
"domain": current_site.domain,
"uid": urlsafe_base64_encode(force_bytes(user.pk)),
"token": generate_email_verification_token(user),
})
send_mail(subject, message, "no-reply@example.com", [user.email])
return render(request, "email_sent.html")
else:
form = CustomUserCreationForm()
return render(request, "register.html", {"form": form})
2.4 認証リンクのビューを作成
ユーザーがメールのリンクをクリックすると、アカウントが有効化されます。
views.py
pythonfrom django.http import HttpResponse
from django.contrib.auth.models import User
from .utils import verify_email_token
def activate_account(request, uidb64, token):
user = verify_email_token(uidb64, token)
if user is not None:
user.is_active = True
user.save()
return HttpResponse("Your account has been activated! You can now log in.")
else:
return HttpResponse("Activation link is invalid!")
2.5 URLの設定
urls.py
に登録用と有効化用のURLを追加します。
pythonfrom django.urls import path
from .views import register, activate_account
urlpatterns = [
path('register/', register, name='register'),
path('activate/<str:uidb64>/<str:token>/', activate_account, name='activate'),
]
2.6 認証メールテンプレート
email_verification.html
htmlHi {{ user.username }}, Please click the link below to verify your email address and activate your account: http://{{ domain }}{% url 'activate' uid=uid token=token %} Thank you!
2.7 メール送信設定
settings.py
にメール送信設定を追加します。
pythonEMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.example.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your_email@example.com'
EMAIL_HOST_PASSWORD = 'your_password'
DEFAULT_FROM_EMAIL = 'no-reply@example.com'
3. テストとデバッグ
- ローカル環境でテストする場合は、
console.EmailBackend
を使用すると、メールがコンソールに出力されます。pythonEMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
- トークン生成やデコードでエラーが出た場合は、例外を確認してください。
4. メリットと応用
- 安全性向上: メール確認を必須にすることで、無効なユーザー登録を防ぎます。
- 通知機能と統合: この仕組みを活用して、パスワードリセットや重要な通知機能にも応用できます。
これで、Djangoでメール認証付きユーザー登録を実現できます!不明点や追加のカスタマイズがあれば、教えてください。