Flask-Login によるユーザー認証

Flask-Login はユーザー認証を簡単に実装できる拡張である。ログイン状態の管理、ログイン必須のルート保護、ユーザーセッションの処理を担う。

セットアップ

pip install flask-login
from flask import Flask
from flask_login import LoginManager

app = Flask(__name__)
app.secret_key = 'your-secret-key'

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

login_view にはログインページのエンドポイント名を指定する。未認証ユーザーが保護されたページにアクセスすると、ここにリダイレクトされる。

ユーザーモデル

ユーザーモデルは UserMixin を継承するか、必要なメソッドを実装する。

from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    password_hash = db.Column(db.String(128))

UserMixin を継承すると、is_authenticatedis_activeis_anonymousget_id メソッドが自動的に提供される。

ユーザーローダー

Flask-Login がセッションからユーザーを復元するために、ユーザーローダー関数を定義する。

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

ログイン処理

from flask_login import login_user, logout_user, current_user
from werkzeug.security import check_password_hash

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        user = User.query.filter_by(username=request.form['username']).first()
        if user and check_password_hash(user.password_hash, request.form['password']):
            login_user(user)
            return redirect(url_for('dashboard'))
    return render_template('login.html')

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

ルートの保護

@login_required デコレータでログイン必須のルートを作れる。

from flask_login import login_required

@app.route('/dashboard')
@login_required
def dashboard():
    return f'Welcome, {current_user.username}!'

current_user は現在ログイン中のユーザーオブジェクトを返す。未認証の場合は匿名ユーザーオブジェクトになる。