はじめに
近年、Web APIはさまざまなアプリケーションやサービス間でデータをやり取りするための重要な手段となっています。特に、セキュリティが重要なAPIでは、認証と認可の仕組みが不可欠です。本記事では、PythonのFlaskフレームワークを使用して、JWT(JSON Web Token)によるセキュアなWeb APIの構築方法を詳しく解説します。初心者の方でも理解できるように、ステップバイステップで進めていきます。
環境構築
PythonとFlaskのインストール
まずは、PythonとFlaskをインストールしましょう。以下のコマンドを実行して、必要なパッケージをインストールします。
pip install flask flask-jwt-extended
これでFlaskとJWTのライブラリがインストールされました。
プロジェクトのディレクトリ構造
次に、プロジェクトのディレクトリ構造を設定します。以下のようにディレクトリを作成してください。
project/
├── app.py
└── data.py
データの準備
まずは、data.pyファイルを作成し、データを準備します。このデータは、APIで使用するサンプルデータです。
data.pyの作成
from datetime import datetime
data = [
{"applicationID": 1, "status": "申請中", "applicationDate": "2024/01/01", "loanTarget": "機器 ZZ01-123", "applicant_userID": "user01", "applicant": "テスト一郎", "loanStartDate": "2024/01/01", "returnDate": "2024/01/31", "approver_userID": "user03", "approver": "上司花子", "loanReason": "出先の使用", "approvalDate": None, "finalApprover_userID": None, "finalApprover": None, "actualReturnDate": None},
# その他のデータ...
]
def filter_and_sort_data(applicant_userID):
filtered_data = [d for d in data if d["applicant_userID"] == applicant_userID]
sorted_data = sorted(filtered_data, key=lambda x: datetime.strptime(x["applicationDate"], "%Y/%m/%d"), reverse=True)
return sorted_data
Flaskアプリケーションの構築
次に、app.pyファイルを作成し、Flaskアプリケーションを構築します。
基本的なFlaskアプリケーションの設定
まずは、Flaskアプリケーションの基本的な設定を行います。
import os
from flask import Flask, request, jsonify
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from data import data, filter_and_sort_data
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = os.urandom(24).hex() # 環境変数を使用することが推奨されます
jwt = JWTManager(app)
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
if username == 'testuser' and password == 'testpassword':
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token), 200
else:
return jsonify({"msg": "Bad username or password"}), 401
@app.route('/applications', methods=['GET'])
@jwt_required()
def get_applications():
applicant_userID = request.args.get('applicant_userID')
if not applicant_userID:
return jsonify({'error': 'applicant_userID is required'}), 400
result = filter_and_sort_data(applicant_userID)
return jsonify(result)
if __name__ == '__main__':
app.run(debug=True)
JWT認証の設定
JWTの仕組み
JWT(JSON Web Token)は、クライアントとサーバー間で情報を安全に転送するためのトークンです。JWTは3つの部分から構成されます:ヘッダー、ペイロード、署名。ヘッダーにはトークンの種類と署名アルゴリズムが含まれ、ペイロードにはユーザー情報などのクレームが含まれます。署名はヘッダーとペイロードを基に生成され、トークンの改ざんを防ぎます。
JWTの生成
Flask-JWT-Extendedを使用して、ユーザーが正しく認証された場合にJWTを生成します。以下のように、ユーザー名とパスワードを検証し、トークンを生成するエンドポイントを設定します。
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
if username == 'testuser' and password == 'testpassword':
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token), 200
else:
return jsonify({"msg": "Bad username or password"}), 401
JWTの検証
JWTを検証するために、Flaskの@jwt_required()デコレータを使用します。これにより、認証が必要なエンドポイントにアクセスする際にトークンが有効かどうかをチェックします。
@app.route('/applications', methods=['GET'])
@jwt_required()
def get_applications():
applicant_userID = request.args.get('applicant_userID')
if not applicant_userID:
return jsonify({'error': 'applicant_userID is required'}), 400
result = filter_and_sort_data(applicant_userID)
return jsonify(result)
環境変数の使用
環境変数の設定
プロダクション環境では、秘密鍵を環境変数に保存することが推奨されます。これにより、コードにハードコーディングせずにセキュリティを確保できます。
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY', 'default_secret_key')
環境変数を設定する方法は、使用しているオペレーティングシステムに依存します。
- Linux/macOS:
export JWT_SECRET_KEY='your_very_secret_key'
- Windows:
set JWT_SECRET_KEY=your_very_secret_key
秘密鍵の管理
環境変数を使用することで、デプロイ環境で秘密鍵を安全に管理することができます。これにより、ソースコードに秘密鍵を含めることなく、セキュリティを向上させることができます。
APIのテスト
curlを使用したテスト
APIが正しく動作することを確認するために、curlを使用してエンドポイントをテストします。
- ログインしてJWTトークンを取得
curl -X POST http://127.0.0.1:5000/login -H "Content-Type: application/json" -d '{"username": "testuser", "password": "testpassword"}'
期待されるレスポンス:
{
"access_token": "your_jwt_token_here"
}
- JWTトークンを使用してデータ取得
取得したトークンを使って、データ取得リクエストを送ります。以下では、your_jwt_token_hereを実際に取得したトークンに置き換えてください。
curl -X GET http://127.0.0.1:5000/applications -H "Authorization: Bearer your_jwt_token_here" -G --data-urlencode "applicant_userID=user01"
期待されるレスポンス:
[
{
"applicationID": 1,
"status": "申請中",
"applicationDate": "2024/01/01",
"loanTarget": "機器 ZZ01-123",
"applicant_userID": "user01",
"applicant": "テスト一郎",
"loanStartDate": "2024/01/01",
"returnDate": "2024/01/31",
"approver_userID": "user03",
"approver": "上司花子",
"loanReason": "出先の使用",
"approvalDate": null,
"finalApprover_userID": null,
"finalApprover": null,
"actualReturnDate": null
},
# その他のデータ...
]
まとめ
本記事では、PythonとFlask、そしてJWTを使用して、初心者向けのセキュアなWeb APIの構築方法を詳細に説明しました。環境構築からデータの準備、Flaskアプリケーションの設定、JWT認証の実装、環境変数の使用、APIのテストまで、すべてのステップをカバーしました。これを基に、自分のプロジェクトでセキュアなWeb APIを構築し、実際に運用することができるでしょう。
セキュリティは継続的なプロセスであり、常に最新の情報を追い、ベストプラクティスを実践することが重要です。本記事がその第一歩となれば幸いです。今後も学習を続け、より安全で信頼性の高いアプリケーションを開発していってください。

