Contents
Flask環境構築とFlask-JWT-Extendedの導入
必要なライブラリのインストール手順
Flask-JWT-Extendedは2026年時点で最も信頼性の高いJWT実装ライブラリとして広く採用されており、旧ライブラリ(Flask-JWT)を使用することは強く推奨しません。以下のコマンドで必要なパッケージをインストールしてください。
-
Python仮想環境の作成
bash
python3 -m venv myapp_env
source myapp_env/bin/activate # Windowsの場合: myapp_env\Scripts\activate -
FlaskとFlask-JWT-Extendedのインストール
bash
pip install Flask flask-jwt-extended
注意: 旧ライブラリ(
flask-jwt)を使用している場合、セキュリティ上のリスクが高いため早急に切り替えることが推奨されます。
仮想環境の作成と依存関係管理
プロジェクト構成を整えることで、依存関係の管理やバージョン制御が容易になります。requirements.txtファイルを作成し、以下のように記述することでデプロイ時の一貫性を保つことが可能です。
|
1 2 3 |
Flask==3.0.0 flask-jwt-extended==4.5.1 |
このファイルを使用して環境構築を行う場合、以下のように実行します。
|
1 2 |
pip install -r requirements.txt |
ユーザー認証用エンドポイントの実装
REST APIにおける認証フローは、ユーザーがアプリケーションにログインし、トークンを取得→検証→API呼び出しという流れで構成されます。以下に具体的な手順を解説します。
ログインエンドポイントの設計と処理フロー
/loginエンドポイントはユーザー認証時に必須です。以下のように、パスワードハッシュ化やデータベース連携を行った実装例を紹介します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from flask import Flask, jsonify, request from flask_jwt_extended import ( create_access_token, jwt_required, get_jwt_identity ) import bcrypt app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'super-secret-key' # プロダクション環境では適切なキーマネジメントを実施してください(例: 環境変数・HSM使用) # サンプルユーザー情報(本番環境ではDBに格納) users_db = { "user1": bcrypt.hashpw(b"password123", bcrypt.gensalt()).decode('utf-8') } @app.route('/login', methods=['POST']) def login(): username = request.json.get('username') password = request.json.get('password') # ユーザーが存在し、パスワードハッシュが一致するか確認 if username in users_db and bcrypt.checkpw(password.encode('utf-8'), users_db[username].encode('utf-8')): access_token = create_access_token(identity=username) return jsonify(access_token=access_token), 200 return jsonify(message="Invalid credentials"), 401 |
注意: パスワードはbcrypt(またはArgon2)でハッシュ化してデータベースに保存し、直接比較しないようにする必要があります。
ユーザー認証ロジックのカスタマイズ方法
Flask-JWT-Extendedでは、ユーザー情報の取得方法をカスタマイズできます。例えば、データベースからユーザー情報を検索する関数を作成し、get_jwt_identity()で取得したIDを使って検証します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from flask import Flask, jsonify, request from flask_jwt_extended import ( create_access_token, jwt_required, get_jwt_identity ) app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'super-secret-key' # データベースの代替としてメモリに保存(実際にはDBを使用) user_datastore = { "user1": {"id": 1, "username": "user1"}, } @app.route('/login', methods=['POST']) def login(): username = request.json.get('username') password = request.json.get('password') # 実際はDB検索とハッシュ比較を行う user_info = user_datastore.get(username) if not user_info or user_info['password'] != password: return jsonify(message="Invalid credentials"), 401 access_token = create_access_token(identity=user_info['id']) return jsonify(access_token=access_token), 200 |
JWTトークンの発行と検証ロジック
Flask-JWT-Extendedでは、create_access_token()メソッドでトークンを生成し、@jwt_required()デコレータで保護されたエンドポイントにアクセスできるようにします。
create_access_tokenメソッドの活用
以下のように、認証成功時にトークンを作成することで、ユーザーが次のAPI呼び出しで検証できます。
|
1 2 3 4 5 6 7 |
from flask_jwt_extended import create_access_token access_token = create_access_token( identity='user123', fresh=True, # フレッシュトークンかどうか設定(詳細は後述) ) |
注意:
freshパラメータは、セッション再認証のタイミングで使用される重要なオプションです。
jwt_requiredデコレータの設定方法
保護されたAPIエンドポイントにアクセスする際には、以下のように@jwt_required()デコレータを追加します。
|
1 2 3 4 5 6 |
@app.route('/protected', methods=['GET']) @jwt_required() def protected(): current_user = get_jwt_identity() return jsonify(logged_in_as=current_user), 200 |
注意: 認証失敗時にはHTTPステータスコードを適切に設定し、エラーメッセージを返すようにしてください。
セキュリティ設計上の注意点
JWT認証を実装する際には、暗号化アルゴリズムやトークン有効期限の設定が非常に重要です。以下に重要な設計ポイントを解説します。
HS256とRS256のアルゴリズム選定基準
| アルゴリズム | 説明 | 使用例 |
|---|---|---|
| HS256(HMAC-SHA256) | シンプルで処理が高速だが、秘密鍵の共有が必要。 | 単一サーバー環境での運用に適する |
| RS256(RSA-SHA256) | 公開・秘密鍵ペアを使用し、中央集約的な管理が可能。 | 複数サーバー環境やクラウドベースの構成に最適 |
注意: HS256は秘密鍵をすべてのサーバーで共有する必要があるため、セキュリティリスクがあります。
トークン有効期限の最適な範囲設定
| 種類 | 推奨有効期限 | 考慮点 |
|---|---|---|
| Access Token | 15分〜30分 | セキュリティとユーザーエクスペリエンスのバランスを取る |
| Refresh Token | 数時間〜数日 | リフレッシュトークンは永続的に保存しないようにする |
注意: 有効期限が長すぎるとセキュリティリスクが高まるため、定期的な刷新メカニズムを設計してください。
最新版Flask-JWT-Extendedでのベストプラクティス
2026年版のFlask-JWT-Extendedでは、非同期処理とリフレッシュトークンのセキュアな管理が新たな焦点となっています。以下に推奨される手法を紹介します。
非同期処理との併用パターン
大量のAPI呼び出しを処理する際には、非同期処理(例: Celery)と組み合わせて負荷分散を行います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from flask import Flask, jsonify from flask_jwt_extended import ( create_access_token, jwt_required, get_jwt_identity ) import celery app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'super-secret-key' celery_app = celery.Celery('tasks', broker='redis://localhost:6379/0') @app.route('/async-task', methods=['POST']) @jwt_required() def async_task(): user_id = get_jwt_identity() task = celery_app.send_task('process_data', args=[user_id]) return jsonify(task_id=task.id), 200 |
注意: 非同期タスクの実行時にJWTの有効性を保証するには、リフレッシュトークンと連携させることをおすすめします。
リフレッシュトークンのセキュアな管理方法
リフレッシュトークンは長期的なアクセスを許可するために使用されるため、適切に管理することが重要です。以下に推奨される実装例を紹介します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from flask_jwt_extended import ( create_access_token, create_refresh_token, jwt_required, get_jwt_identity, get_jwt_claims ) @app.route('/login', methods=['POST']) def login(): # 認証処理 access_token = create_access_token(identity='user123') refresh_token = create_refresh_token(identity='user123') return jsonify(access_token=access_token, refresh_token=refresh_token), 200 @app.route('/refresh', methods=['POST']) @jwt_required(refresh=True) def refresh(): current_user = get_jwt_identity() access_token = create_access_token(identity=current_user) return jsonify(access_token=access_token), 200 |
注意: リフレッシュトークンは、アクセストークンよりも有効期限を長く設定し、リフレッシュAPIの呼び出し回数を制限する必要があります。
まとめ
- Flask-JWT-Extendedを使用してJWT認証を実装することで、APIセキュリティを強化できます
- ユーザー認証用エンドポイントとトークン発行ロジックの設計が重要です
- 暗号化アルゴリズムやトークン有効期限は、2026年の最新ガイドラインに従って設定してください
- 非同期処理との併用やリフレッシュトークンのセキュアな管理も忘れずに
これらの手順を踏むことで、安全で信頼性の高いFlaskアプリケーションが構築できます。本記事の実装方法に従って、JWT認証を導入し、APIセキュリティを強化してみてください。