Flaskでパスワードリセット機能を実装する流れを初心者向けに解説【完全ガイド】
生徒
「先生、Webアプリでログイン機能を作ったんですが、もしユーザーがパスワードを忘れた場合ってどうしたらいいんでしょうか?」
先生
「その場合は『パスワードリセット機能』を作るんです。登録しているメールアドレスにリンクを送って、新しいパスワードを設定してもらう仕組みですね。」
生徒
「へぇ〜!でもメール送信とかリンク生成って、難しそうです……初心者でもできますか?」
先生
「もちろんできますよ!Flaskには便利な拡張機能があるので、順番にやれば誰でも作れます。今日は、初心者でも理解できるように一つずつ説明しますね。」
1. パスワードリセット機能とは?
Webアプリケーションでは、ユーザーがパスワードを忘れてしまうことがあります。そのときに役立つのがパスワードリセット機能です。
例えば、AmazonやTwitterでも「パスワードを忘れた方はこちら」というリンクを見たことがありますよね?クリックするとメールが届いて、そこから新しいパスワードを設定できます。
Flaskでも同じ仕組みを作ることができます。やることはシンプルで、以下の流れです。
- ① ユーザーが「パスワードを忘れた」ボタンを押す
- ② 登録済みメールアドレスを入力する
- ③ Flaskがリセット用リンクを生成して、そのメールに送信する
- ④ ユーザーがメールのリンクをクリック
- ⑤ 新しいパスワードを入力してリセット完了!
つまり、「本人確認をメールで行い、安全にパスワードを変更する」仕組みです。
2. Flask-Mailを使ってメール送信を設定しよう
Flaskでメールを送信するには、Flask-Mailという拡張機能を使います。これはGmailなどのSMTP(エスエムティーピー:メールを送る仕組み)を使ってメールを送るツールです。
まず、ライブラリをインストールしましょう。
pip install Flask-Mail
次に、Flaskアプリに設定を追加します。
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
# メールサーバーの設定
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'あなたのメールアドレス@gmail.com'
app.config['MAIL_PASSWORD'] = 'アプリパスワード' # Gmailのアプリパスワードを使用
mail = Mail(app)
ここで出てきた「アプリパスワード」は、Googleアカウントの設定から発行できる特別なパスワードです。普段のログイン用パスワードを使うのはNGです。
3. パスワードリセット用のトークンを作る
リセットリンクには、他人が勝手に使えないように安全なトークン(暗号化された一時的なキー)を付けます。これを作るのに便利なのがitsdangerous(イッツデンジャラス)というライブラリです。
インストールして使ってみましょう。
pip install itsdangerous
from itsdangerous import URLSafeTimedSerializer
s = URLSafeTimedSerializer('シークレットキー')
def generate_reset_token(email):
return s.dumps(email, salt='password-reset')
def confirm_reset_token(token, expiration=3600):
try:
email = s.loads(token, salt='password-reset', max_age=expiration)
except:
return None
return email
このトークンは暗号化されていて、1時間などの期限を設定することもできます。期限を過ぎたトークンは無効になるので安全です。
4. ユーザーがリセットを申請したときの処理
次に、ユーザーが「パスワードを忘れた」ページからメールアドレスを送信したときの処理を書きます。ここでリセット用リンクを生成してメールを送ります。
from flask import request, url_for
@app.route('/reset_request', methods=['POST'])
def reset_request():
email = request.form['email']
token = generate_reset_token(email)
reset_link = url_for('reset_password', token=token, _external=True)
msg = Message('パスワードリセット', sender='あなたのメールアドレス@gmail.com', recipients=[email])
msg.body = f'以下のリンクから新しいパスワードを設定してください:\n{reset_link}'
mail.send(msg)
return 'パスワードリセット用のメールを送信しました。'
このようにして、Flaskアプリがユーザーに安全なリンクをメールで送ります。
5. メールのリンクから新しいパスワードを設定する
ユーザーがメールのリンクをクリックしたら、Flaskがトークンを検証し、新しいパスワードを設定するページを表示します。
@app.route('/reset/<token>', methods=['GET', 'POST'])
def reset_password(token):
email = confirm_reset_token(token)
if not email:
return 'リンクが無効または期限切れです。'
if request.method == 'POST':
new_password = request.form['password']
# ここでデータベースのパスワードを更新する処理(省略)
return 'パスワードを更新しました!'
return '''
<form method="post">
<input type="password" name="password" placeholder="新しいパスワード">
<button type="submit">更新</button>
</form>
'''
このコードでは、メールアドレスをトークンから復元して本人確認を行い、フォームから入力された新しいパスワードで更新します。
6. セキュリティ上の注意点
パスワードリセット機能はとても便利ですが、セキュリティ上の注意も必要です。
- ・トークンは短い時間(例:1時間)で失効させる
- ・メールアドレスの存在を画面上で明示しない(「そのメールは登録されていません」と表示しない)
- ・パスワードは必ずハッシュ化して保存する(例:
werkzeug.securityのgenerate_password_hashを使う) - ・メール送信元を公式のドメインにすることで信頼性を高める
これらを守ることで、より安全なFlaskアプリケーションを作ることができます。
7. 実際の使い方の流れをイメージしよう
ここまでの流れを整理すると、Flaskでのパスワードリセットは以下のようなイメージです。
- ① 「パスワードを忘れた?」ボタンをクリック
- ② Flaskが入力されたメールを確認
- ③ トークン付きのURLをメールで送信
- ④ ユーザーがメールを開き、リンクをクリック
- ⑤ 新しいパスワードを入力して完了!
たとえるなら、郵便で「本人しか開けられない封筒」を送るようなものです。トークンはその封筒の鍵のような役割を果たしています。
8. Flaskでパスワードリセットを導入するメリット
Flaskでパスワードリセット機能を実装するメリットは、ユーザーの利便性とセキュリティの両立です。ユーザーが安心して使えるアプリを提供できることはもちろん、運営側にとっても「問い合わせ対応の手間」を減らせます。
さらに、Flask-Mailやitsdangerousは軽量で柔軟なので、将来的にSMS認証や2段階認証(2FA)などを追加したい場合にも拡張しやすいです。