PR

【Python】初心者向けPythonでのセキュアなWEB-API構築: FlaskとJWTを用いた実例

【Python】
広告

はじめに

近年、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を使用してエンドポイントをテストします。

  1. ログインして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"
}
  1. 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を構築し、実際に運用することができるでしょう。

セキュリティは継続的なプロセスであり、常に最新の情報を追い、ベストプラクティスを実践することが重要です。本記事がその第一歩となれば幸いです。今後も学習を続け、より安全で信頼性の高いアプリケーションを開発していってください。

広告
【Python】
広告
タイトルとURLをコピーしました