LoginSignup
9
13

More than 5 years have passed since last update.

Python + Djangoでパスワードリセット画面を実装する

Last updated at Posted at 2018-07-30

Djangoのパスワードリセット機能を試します。

以下のリンクの続きです。
Python + Djangoで独自のユーザ認証を実装する
Python + Djangoでパスワード変更画面を実装する

1.パスワードリセットのフロー

パスワードリセットは、システム上で、メールアドレスを入力して送信し、ユーザはメール受信後に、本文に記載されているURLをクリックします。パスワード変更画面(パスワードリセット用)が開くので、パスワードを変更すると、パスワードリセット完了の画面が表示され完了します。

  • (1)パスワードリセット(メールアドレス入力)画面
  • (2)パスワードリセット(メール送信)画面
  • (3)メールのURLをクリック
  • (4)パスワードリセット(パスワード変更)画面
  • (5)パスワードリセット(パスワードリセット完了)画面

Djangoでは、このパスワードリセットも最初から実装されているのでそれを利用します。

2.実装

(1)accounts\urls.py

パスワードリセット用に、URLを4つ追加します。

accounts\urls.py
from django.urls import path
from . import views

app_name = 'accounts'
urlpatterns = [
    path('', views.index.as_view(), name='index'),
    path('password_change/', views.PasswordChange.as_view(), name='password_change'),
    path('password_change/done/', views.PasswordChangeDone.as_view(), name='password_change_done'),
    path('password_reset/', views.PasswordReset.as_view(), name='password_reset'), #追加
    path('password_reset/done/', views.PasswordResetDone.as_view(), name='password_reset_done'), #追加
    path('reset/<uidb64>/<token>/', views.PasswordResetConfirm.as_view(), name='password_reset_confirm'), #追加
    path('reset/done/', views.PasswordResetComplete.as_view(), name='password_reset_complete'), #追加
]

(2)accounts\views.py

パスワードリセット用に、views.pyを編集します。formクラスはDjangoで用意されているのでそのまま利用します。

accounts\views.py
from django.shortcuts import render
# PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteViewを追加
from django.contrib.auth.views import PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import generic
from django.urls import reverse_lazy

class index(LoginRequiredMixin, generic.TemplateView):
    """メニュービュー"""
    template_name = 'accounts/top.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs) # 継承元のメソッドCALL
        context["form_name"] = "top"
        return context


class PasswordChange(LoginRequiredMixin, PasswordChangeView):
    """パスワード変更ビュー"""
    success_url = reverse_lazy('accounts:password_change_done')
    template_name = 'accounts/password_change.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs) # 継承元のメソッドCALL
        context["form_name"] = "password_change"
        return context


class PasswordChangeDone(LoginRequiredMixin,PasswordChangeDoneView):
    """パスワード変更しました"""
    template_name = 'accounts/password_change_done.html'

# --- ここから追加
class PasswordReset(PasswordResetView):
    """パスワード変更用URLの送付ページ"""
    subject_template_name = 'accounts/mail_template/reset/subject.txt'
    email_template_name = 'accounts/mail_template/reset/message.txt'
    template_name = 'accounts/password_reset_form.html'
    success_url = reverse_lazy('accounts:password_reset_done')


class PasswordResetDone(PasswordResetDoneView):
    """パスワード変更用URLを送りましたページ"""
    template_name = 'accounts/password_reset_done.html'


class PasswordResetConfirm(PasswordResetConfirmView):
    """新パスワード入力ページ"""
    success_url = reverse_lazy('accounts:password_reset_complete')
    template_name = 'accounts/password_reset_confirm.html'


class PasswordResetComplete(PasswordResetCompleteView):
    """新パスワード設定しましたページ"""
    template_name = 'accounts/password_reset_complete.html'

# --- ここまで

(3)templates\accounts\password_reset_form.html

templates\accounts\password_reset_form.html
{% extends "commons/base.html" %}
{% block headertitle %}
  パスワードリセット
{% endblock %}
{% block content %}
<form action="" method="POST">
    {{ form.non_field_errors }}
    <p>メールを受信してパスワードの変更手続きを行います。</p>
    <p>メールアドレスを入力して送信ボタンを押してください。</p>
    {% for field in form %}
    <div class="form-group">
        <label for="{{ field.id_for_label }}">{{ field.label_tag }}</label>
        {{ field }}
        {{ field.errors }}
    </div>
    {% endfor %}
    {% csrf_token %}

    <pre>メールアドレスはあらかじめシステムに登録が必要です。
メールが届かない場合はシステム管理者に連絡してください。</pre>
    <br/>
    <div class="form-group row">
      <div class="col-6">
        <button type="submit" class="btn btn-primary btn-block">送信</button>
      </div>
    </div>
</form>
{% endblock %}

(4)templates\accounts\password_reset_done.html

templates\accounts\password_reset_done.html
{% extends "commons/base.html" %}

{% block headertitle %}
  パスワードリセット(メール送信)
{% endblock %}

{% block content %}
<form action="" method="POST">
<p>パスワードリセットのメールを送信しました。
<br/>
メールに記載されているリンクからパスワードの再設定を行ってください。
<br/>
<br/>
<br/>
<a class="btn btn-primary col-4" href="{% url 'accounts:index' %}">ログイン画面へ</a>
</p>
</form>
{% endblock %}

(5)templates\accounts\password_reset_confirm.html

templates\accounts\password_reset_confirm.html
{% extends "commons/base.html" %}
{% block content %}
<form action="" method="POST">
    {{ form.non_field_errors }}
    {% for field in form %}
    <div class="form-group">
        <label for="{{ field.id_for_label }}">{{ field.label_tag }}</label>
        {{ field }}
        {{ field.errors }}
    </div>
    {% endfor %}
    {% csrf_token %}
    <button type="submit" class="btn btn-primary btn-block">送信</button>
</form>
{% endblock %}

(6)templates\accounts\password_reset_complete.html

templates\accounts\password_reset_complete.html
{% extends "commons/base.html" %}
{% block content %}
<form action="" method="POST">
<p>
    パスワード再設定を完了しました。<br>
    <a class="btn btn-primary btn-block" href="{% url 'accounts:index' %}">ログイン</a>
</p>
</form>
{% endblock %}

以上で実装終わりです。

※パスワードリセット(メールアドレス入力)画面で入力するメールアドレスは、プロジェクトの認証ユーザに設定されているメールアドレスである必要があります。管理サイトからメールアドレスを設定しましょう。

image.png

3.動作確認

では、確認してみます。

(1)パスワードリセット(メールアドレス入力)画面

image.png

(2)パスワードリセット(メール送信)画面

image.png

(3)メール

送信されたメール。ユーザ:Djangoに設定したメールアドレスに送信されています。

django 様


下記URLよりサイトにアクセスし、パスワードの再設定を行ってください。


再設定用URL
http://localhost:8000/reset/MQ/4yb-77d2a24a746ddeceb805/

(4)パスワードリセット(パスワード変更)画面

image.png

(5)パスワードリセット(パスワードリセット完了)画面

image.png

パスワードリセットもDjangoは簡単です。

9
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
13