Contents
Flask REST API 認証 JWT 実装 方法:Flask-JWT-Extendedを使ったステップバイステップガイド
FlaskでREST APIを構築する際、セキュアな認証仕組みの実装は必須です。特にJWT(JSON Web Token)は軽量かつ柔軟性のある認証方式として広く採用されており、2026年の現在ではFlask-JWT-Extendedが主流です。本記事では、環境構築からトークン発行、アクセス制御(RBAC)設計、セキュリティベストプラクティスまでを具体的に解説し、読者が実際にコードを書けるレベルまで指導します。
Flask環境構築と必要なライブラリのインストール方法
FlaskアプリケーションでJWT認証を利用するには、事前に開発環境を整える必要があります。Python仮想環境の作成から、必要ライブラリのバージョン管理までを具体的に解説します。
Python仮想環境の作成
- 仮想環境用ディレクトリを作成します(例:
myapp/)。 venvまたはpipenvで仮想環境を生成します。
bash
python3 -m venv myapp/venv
source myapp/venv/bin/activate # macOS/Linux
myapp\venv\Scripts\Activate.ps1 # Windows(PowerShell)
- プロジェクトルートに
requirements.txtを配置し、依存ライブラリのバージョン管理を行います。
flask, Flask-JWT-Extendedの導入手順
以下は最新バージョン(2026年7月時点)でのインストール手順です。
-
requirements.txtに以下の内容を記述します:
Flask==3.0.0
Flask-JWT-Extended==5.1.0
python-dotenv==1.0.0 # 環境変数管理用ライブラリ -
仮想環境内でインストールします:
bash
pip install -r requirements.txt
注意:Flask-JWT(非推奨ライブラリ)は使用しないようにしてください。最新の
Flask-JWT-Extendedが公式に推奨されています。
JWTトークン発行ロジックの実装(ユーザー認証API設計)
JWT認証では、ユーザーIDとロール情報を含むトークンを発行し、リソースへのアクセス権を付与します。以下に/loginエンドポイントでのトークン発行フローを実装します。
ユーザーログインエンドポイントの作成
app.pyに基本的なFlask構成を記述します:
python
from flask import Flask, jsonify, request
from flask_jwt_extended import (
JWTManager, create_access_token,
jwt_required, get_jwt_identity
)
import os
app = Flask(name)
# 環境変数からJWT_SECRET_KEYを読み込む(後述の設定方法参照)
app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET_KEY', 'fallback-secret-key')
jwt = JWTManager(app)
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
|
1 2 3 4 5 6 |
# ユーザー認証ロジック(簡略化) if username == 'admin' and password == 'secret': access_token = create_access_token(identity=username) # identityは文字列/整数のみが前提 return jsonify(access_token=access_token), 200 return jsonify(error='Invalid credentials'), 401 |
if name == 'main':
app.run(debug=True)
ポイント:
create_access_token()はFlask-JWT-Extendedが管理する秘密鍵でトークンを生成します。identityには辞書ではなく、文字列/整数を渡す必要があります(例:username)。環境変数でのJWT_SECRET_KEY管理の具体的手順については後述します。
アクセス制御(RBAC)の実装例
ロールベースアクセス制限(RBAC)では、トークン内にユーザーのロール情報を含め、特定のエンドポイントへのアクセスを制御します。以下に管理者専用エンドポイントの例を示します。
ロールベースのアクセス制限
-
トークンにロール情報を付与する(※identityには辞書型は使わない):
python
# セキュリティ上、identityに辞書型は使用不可。代わりにユーザーIDを渡す
access_token = create_access_token(identity=user_id) -
ロール情報をトークンのペイロードに追加する:
python
from flask_jwt_extended import set_access_cookies, get_jwt
@app.route('/login', methods=['POST'])
def login():
# ...認証ロジック...
access_token = create_access_token(identity=user_id)
response = jsonify(access_token=access_token)
# ペイロードにrole情報を追加(カスタムクレーム)
response.set_cookie('access_token', access_token, httponly=True, secure=True)
return response
- 管理者専用エンドポイントを作成し、
@jwt_required()で認証を強制します:
python
@app.route('/admin', methods=['GET'])
@jwt_required()
def admin():
current_user = get_jwt_identity() # identityからユーザーID取得
return jsonify(message=f"Hello, {current_user} (Admin)"), 200
比較表:RBACの実装方法の選択肢
| メソッド | 説明 | 適用例 |
|---|---|---|
@jwt_required() |
基本的なトークン認証 | 全エンドポイント共通 |
@roles_required('admin') |
特定ロールのアクセス制限 | 管理者専用API |
トークン検証ミドルウェアの作成手順
全エンドポイントに共通する認証処理を実装するには、ミドルウェアとして@jwt_required()デコレーターを使用します。
@jwt_required()デコレーターの設定
-
保護されたエンドポイントに
@jwt_required()を追加します:
python
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
return jsonify(message="This is a protected endpoint"), 200 -
トークンが無効または期限切れの場合、自動的に401エラーを返します。
セキュリティ設計のポイントとベストプラクティス
JWTは軽量ですが、誤った設計でセキュリティリスクに晒される可能性があります。以下の点に注意しましょう。
署名アルゴリズム(HS256 vs RS256)の選定理由
| アルゴリズム | 説明 | 推奨用途 |
|---|---|---|
| HS256 | HMAC-SHA256。シンプルだが秘密鍵をクライアント側に共有する必要がある | 小規模なプロジェクト |
| RS256 | RSA-SHA256。公開鍵/秘密鍵ペアで署名。秘密鍵はサーバー側のみ保持可能 | 本番環境、セキュリティ重視のシステム |
RS256の実装手順:
- 公開鍵と秘密鍵を生成(例:
openssl genrsa -out private_key.pem 2048) - 秘密鍵をサーバー側に、公開鍵をクライアント側に配置
- Flask-JWT-ExtendedでRS256を有効化:
python
app.config['JWT_ALGORITHM'] = 'RS256'
環境変数でのJWT_SECRET_KEY管理の具体的手順
本番環境では、JWT_SECRET_KEYをハードコーディングせずに環境変数で管理する必要があります。
手順
-
.envファイルを作成し、以下の内容を記述します:
JWT_SECRET_KEY=your-very-secret-key -
requirements.txtにpython-dotenvを追加し、インストールします。 -
アプリケーションの初期化時に環境変数を読み込みます:
python
from dotenv import load_dotenv
import os
load_dotenv()
app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET_KEY')
注意:
.envファイルは.gitignoreに追加し、リポジトリに含めないよう管理してください。
ローカル環境での動作確認とサンプルコード実行ガイド
以下の手順で、本文に記載したコードをローカル環境でテストします。
postman/curlによるテスト手順
-
トークン取得:
bash
curl -X POST http://localhost:5000/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "secret"}'
→ トークンが返るはずです。 -
保護されたエンドポイントテスト:
bash
curl -X GET http://localhost:5000/protected \
-H "Authorization: Bearer <取得したトークン>"
デバッグ方法:
flask run --debuggerでデバッガーを有効にし、認証フローのステップを追跡できます。
まとめ
- Flask環境構築には仮想環境と
Flask-JWT-Extendedの導入が不可欠です /loginエンドポイントでトークン発行ロジックを実装し、create_access_token()を使用します(identityは文字列/整数に限る)- RBACは
@jwt_required()とget_jwt_identity()でロール情報を取得して制限をかけることで実現可能です - トークン検証にはミドルウェアとしてのデコレーターが有効です
- セキュリティ設計では、RS256アルゴリズムと環境変数による秘密鍵管理が重要です
JWT認証の導入は、Flaskアプリケーションのセキュリティを飛躍的に高める手法です。本文で記載したコードを参考に、ローカル環境で動作確認を行いながら実装してください。