Flaskで権限別にページアクセスを制御する方法(RBAC)を初心者向けに徹底解説!
生徒
「先生、Flaskでログイン機能を作ったんですが、全員が同じページにアクセスできてしまいます。管理者だけが入れるページを作りたいんです。」
先生
「いいところに気づきましたね。Flaskでは“権限(けんげん)”を使って、ユーザーの種類ごとにアクセスできるページを制限することができます。」
生徒
「権限って、たとえば“管理者(Admin)”と“普通のユーザー(User)”を分ける感じですか?」
先生
「その通り!今日は“RBAC(ロールベースアクセス制御)”という仕組みを使って、Flaskで権限ごとにページのアクセスを制御する方法を学びましょう。」
1. RBAC(ロールベースアクセス制御)とは?
RBACとは「Role-Based Access Control(ロールベースアクセス制御)」の略です。日本語では「役割に基づくアクセス制御」と呼ばれます。これは、ユーザーの“役割(ロール)”によってアクセスできるページや操作を分ける仕組みです。
たとえば次のような感じです。
- 管理者(Admin):全ページにアクセスできる
- 一般ユーザー(User):自分のページだけアクセスできる
- ゲスト(Guest):ログインページしか見れない
このように、ユーザーの「立場」や「責任」に応じてアクセス権限を制御するのがRBACです。
2. FlaskでRBACを実装するための考え方
FlaskでRBACを実装するには、まずユーザーがどの権限を持っているかを記録する必要があります。これは、ログイン時にユーザー情報と一緒にセッション(Session)に保存するのが基本です。
セッションとは、Flaskがユーザーごとに一時的に情報を保存しておく仕組みです。これにより、ページを移動しても「誰がログインしているか」「どの権限を持っているか」を覚えておくことができます。
3. Flaskで権限別にページを制御する基本コード
それでは、FlaskでRBACを実装するシンプルなサンプルコードを見てみましょう。
from flask import Flask, session, redirect, url_for, request, render_template_string
app = Flask(__name__)
app.secret_key = 'secret_key_1234'
# サンプルユーザー情報
users = {
'admin': {'password': 'adminpass', 'role': 'admin'},
'taro': {'password': 'userpass', 'role': 'user'}
}
@app.route('/')
def home():
if 'username' in session:
return f"ようこそ、{session['username']}さん!(権限:{session['role']})"
return "ログインしていません。<a href='/login'>ログインページへ</a>"
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username in users and users[username]['password'] == password:
session['username'] = username
session['role'] = users[username]['role']
return redirect(url_for('home'))
return "ユーザー名またはパスワードが間違っています。"
return render_template_string('''
<form method="post">
ユーザー名:<input name="username"><br>
パスワード:<input name="password" type="password"><br>
<input type="submit" value="ログイン">
</form>
''')
@app.route('/admin')
def admin_page():
if session.get('role') != 'admin':
return "アクセス権限がありません。<a href='/'>戻る</a>"
return "これは管理者専用ページです!"
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('home'))
このコードでは、ログイン時にユーザーの「権限(role)」をセッションに保存しています。そして、/admin ページでは、ログイン中のユーザーの権限を確認し、adminでなければアクセスを拒否します。
4. RBACを理解するためのたとえ話
イメージしやすくするために、学校の例で考えてみましょう。
学校には「先生」「生徒」「来客」という3つの立場があります。それぞれの人が入れる場所は決まっています。
- 先生:職員室・教室・校庭すべてOK
- 生徒:教室・校庭はOK、職員室はNG
- 来客:受付エリアのみOK
この仕組みがまさにRBACです。Flaskでは、この「誰がどの部屋に入れるか」をプログラムで判断しているのです。
5. デコレーターで権限チェックを自動化しよう
毎回「if文」で権限をチェックするのは面倒です。Flaskでは「デコレーター」という便利な仕組みを使うと、共通の処理をまとめて書けます。
from functools import wraps
def role_required(role):
def wrapper(func):
@wraps(func)
def decorated_function(*args, **kwargs):
if session.get('role') != role:
return "アクセス権限がありません。"
return func(*args, **kwargs)
return decorated_function
return wrapper
@app.route('/admin-dashboard')
@role_required('admin')
def admin_dashboard():
return "ここは管理者専用ダッシュボードです。"
@role_required('admin')という書き方をすることで、特定のページを「admin」だけが見られるように制御できます。
6. RBACを使うときの注意点
RBACは便利ですが、いくつか注意点もあります。
- セッションの改ざんを防ぐため、必ず
secret_keyを設定する。 - ログイン後に権限情報を確認する。 セッションが古い場合は再ログインさせるのが安全です。
- アクセスログを取る。 どのユーザーがどのページにアクセスしたかを記録することで、不正な操作を防げます。
7. RBACの応用:複数権限のチェック
実際のアプリケーションでは、1つのページに複数の権限を許可したい場合もあります。たとえば「管理者とマネージャーだけ見られるページ」です。
def roles_required(*roles):
def wrapper(func):
@wraps(func)
def decorated_function(*args, **kwargs):
if session.get('role') not in roles:
return "アクセス権限がありません。"
return func(*args, **kwargs)
return decorated_function
return wrapper
@app.route('/manager-page')
@roles_required('admin', 'manager')
def manager_page():
return "ここは管理者またはマネージャー専用ページです。"
このように、柔軟なアクセス制御を簡単に作ることができます。
8. 権限別アクセス制御の全体像をまとめてイメージしよう
FlaskのRBACをイメージで説明すると、「受付で身分証を確認して、入れる部屋を決める」ような仕組みです。ログイン時に“誰か”を確認し、その人が持つ“権限”によって、通れるドア(ページ)を制限します。
この仕組みをしっかり理解しておくと、Flaskで作るWebアプリが安全で信頼できるものになります。