メインコンテンツへスキップ

Flask でユーザー認証の仕組みを入れる(後編)

·2 分
ひとりアドベントカレンダー2024 Python Flask Flask-Login
目次

はじめに
#

「OKAZAKI Shogo のひとりアドベントカレンダー2024」の13日目です。 昨日整理を行なった各種ページですが、ようやく、ログイン機能を実装し、すでにあるページで認証済みでないと遷移できないページに設定を入れます。

ログイン処理の実装
#

app/templates/login.html
#

まずは、簡単にログイン画面のテンプレートを作成する。

 1{% extends "layout-general.html" %}
 2
 3{% block content %}
 4<body>
 5    <h2>{{ page_title }}</h2>
 6    <form action="/login" method="post">
 7        {% with messages = get_flashed_messages() %}
 8        {% if messages %}
 9        <ul>
10          {% for message in messages %}
11          <li>{{ message }}</li>
12          {% endfor %}
13        </ul>
14        {% endif %}
15        {% endwith %}
16        <label for="username">ユーザー名:</label>
17        <input type="text" id="username" name="username" required><br><br>
18
19        <label for="password">パスワード:</label>
20        <input type="password" id="password" name="password" required><br><br>
21
22        <button type="submit">ログイン</button>
23    </form>
24</body>
25{% endblock %}

app/views/login.py
#

実際のログイン処理を実装する。

  • 入力されたユーザー名からユーザー情報を取得する。
  • ユーザー情報があれば、入力されたパスワードの検証を行う
    • 前編で入れたように、パスワードはハッシュ値を元に検証を行う。
 1from flask import Blueprint, flash, redirect, render_template, request, url_for
 2from flask_login import login_user
 3
 4from app.models.manager_user import ManagerUser
 5
 6login_bp = Blueprint("login", __name__, url_prefix="/login")
 7
 8
 9@login_bp.route("/", methods=["GET", "POST"])
10def index():
11    if request.method == "POST":
12        username = request.form.get("username")
13        password = request.form.get("password")
14        # ManagerUserテーブルからusernameに一致するユーザを取得
15        user = ManagerUser.query.filter_by(user_name=username).first()
16        if user is None or not user.check_password(password):
17            flash("無効なユーザー ID かパスワードです。")
18            return redirect(url_for("login.index"))
19        login_user(user)
20        return redirect(url_for("manage_menu.index"))
21    return render_template("login.html", page_title="管理者向けログイン")

ログアウトの処理の実装
#

前編で解説した通り、Flask-Login の仕組みでは、クッキーにユーザーの情報を保存するので、それを消去するために flask_login.logout_user() を呼び出す。

 1from flask import Blueprint, redirect, url_for
 2from flask_login import logout_user
 3
 4logout_bp = Blueprint("logout", __name__, url_prefix="/logout")
 5
 6
 7@logout_bp.route("/", methods=["GET", "POST"])
 8def index():
 9    logout_user()
10    return redirect(url_for("login.index"))

ログインが必要なページへの設定
#

@login_required をつければ良い。

1@manage_file_list_bp.route("/", methods=["GET"])
2@login_required
3def index():
4    # 以下略

動作の確認
#

まずはトップページ。この時点でセッションは何も保存されていないとわかる。

動作例1

ログイン画面。

動作例2

ログイン完了した後。セッションにユーザー情報が保存されている。

動作例3

ログインが必要な画面への遷移。依然として、セッションにユーザー情報が保存されている。

動作例4

動作例5

ログアウトすると、クッキーの情報が消える。

動作例6

ログアウトした状態で認証が必要なページに遷移すると、 403 エラーが表示される。

動作例7