JWT 認証APIシステム構築手順書
Ver1.0.0 まずは体験 - 動くものを作る
ゴール
小さなマイクロ認証サーバー(auth_server)を作成し、JWT発行機能を最小で完成させる。
チェックリスト
- [ ] 1. ディレクトリ
jwt_micro_system/auth_server/
を作成する - [ ] 2.
config.py
を作成する(secret_keyとissuerを定義) - [ ] 3.
app.py
を作成する(/loginエンドポイント) - [ ] 4.
requirements.txt
を作成する(Flask, PyJWT) - [ ] 5. ライブラリインストール(
pip install -r requirements.txt
) - [ ] 6. Flaskサーバーを起動する(
python app.py
) - [ ] 7. curlコマンドで/loginを叩いてJWTトークン発行テスト
- [ ] 8. 発行されたJWTの中身を確認する(sub, role, iat, exp, iss)
ディレクトリ構成
- ディレクトリ jwt_micro_system/auth_server/ を作成
jwt_micro_system/
├── auth_server/
│ ├── app.py # Flaskのエントリーポイント
│ ├── config.py # 設定ファイル(secret_key, issuer)
│ ├── requirements.txt # 依存ライブラリリスト
│ └── README.md # auth_server単体のメモ(curl例など)
├── shared/
│ └── jwt_helper.py # (将来)共通JWTヘルパー関数
└── progress.md # 進捗管理ファイル(このファイル)
Program Code
config.py
を作成する(secret_keyとissuerを定義)
# auth_server/config.py
SECRET_KEY = 'your-very-secret' # テスト用の秘密鍵(あとで強化できる)
ISSUER = 'Your Identity' # あなたの固有識別子
app.py
を作成する(/loginエンドポイント)
# auth_server/app.py
from flask import Flask, request, jsonify
import jwt
import datetime
from config import SECRET_KEY, ISSUER
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
user_id = data.get('user_id')
role = data.get('role', 'user') # roleは任意(指定がなければ"user")
if not user_id:
return jsonify({'error': 'user_id is required'}), 400
# JWTペイロード
payload = {
'sub': user_id,
'role': role,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30), # 30分有効
'iss': ISSUER
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return jsonify({'token': token})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=10000, debug=True)
requirements.txt
を作成する(Flask, PyJWTなど)
auth_server/requirements.txt
Flask
PyJWT
python-dotenv
- pip install
pip install -r auth_server/requirements.txt
- Flaskサーバー起動
python auth_server/app.py
- jwtトークン発行
実行curlコマンド
curl -X POST http://localhost:10000/login \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "role": "admin"}'
- jwtデコード 結果
{
"token": "abcdefghijklmnopqrstuvwxyz01234567890"
}
ENCODED VALUE
abcdefghijklmnopqrstuvwxyz01234567890
DECODED HEADER |キー|説明| |---|---| |alg|algorithm 署名に用いられるアルゴリズム| |typ|type トークンの種類の識別|
{
"alg": "HS256",
"typ": "JWT"
}
DECODED PAYLOAD |キー|説明| |---|---| |sub|subject 主語| |role|role 役職| |iat|issue at 発行日| |exp|expire 有効期限| |iss|issuer 発行機関元|
{
"sub": "user123",
"role": "admin",
"iat": 1746664230,
"exp": 1746666030,
"iss": "Your Identity"
}
Ver1.1.0 セキュリティ向上 - 環境変数管理化
ゴール
secret_keyなどの気密性の高い情報を環境変数管理に移し、セキュリティを向上させる。
チェックリスト
- [ ] 0. ディレクトリ
jwt_micro_system/auth_server/
を更新する - [ ] 1.
.env
ファイルを作成する(secret_keyなどを記述) - [ ] 2.
python-dotenv
ライブラリを導入する(pip install python-dotenv
) - [ ] 3.
config.py
を書き換え、環境変数から値を読むように修正する - [ ] 4.
.gitignore
に.env
を追加して、秘密情報をGit管理対象外にする - [ ] 5. Flaskアプリを起動し、JWT発行が正常に動作するかテストする
- [ ] 6.
progress.md
に Ver1.1.0 の作業結果を追記・整理する
- ディレクトリ構成
jwt_micro_system/
├── auth_server/
│ ├── app.py # Flaskエントリーポイント(コードは少しだけ修正)
│ ├── config.py # 📝 設定ファイル(環境変数から読む形に修正)
│ ├── .env # 🆕 秘密情報を管理するファイル
│ ├── requirements.txt # ライブラリリスト(python-dotenvを追加)
│ └── README.md # auth_server単体のドキュメント
├── shared/
│ └── jwt_helper.py # 共通処理(将来拡張、今は空でOK)
├── .gitignore # 🆕 .envをgit対象外にする
└── progress.md # 進捗管理ファイル(Ver1.1.0を追記)
- .env新規作成
# auth_server/.env
SECRET_KEY=your-very-secret-key
ISSUER=your identity
- python-dotenvライブラリ導入
インストール
pip install python-dotenv
確認
pip list | grep dotenv
結果
python-dotenv 1.1.0
- envファイルからのロード(機密事項を隠すため)
# auth_server/config.py
from dotenv import load_dotenv
import os
# .envファイルをロード
load_dotenv()
# 環境変数から読み取る
SECRET_KEY = os.getenv('SECRET_KEY')
ISSUER = os.getenv('ISSUER')
- .gitignore(.envファイルとPythonキャッシュファイルを除外する)
# .gitignore
# Python関連
__pycache__/
*.pyc
# 環境変数ファイル
auth_server/.env
- 動作確認
サーバー起動
python auth_server/app.py
実行コマンド
curl -X POST http://localhost:10000/login \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "role": "admin"}'
実行結果
{
"token": "abcdefghijklmnopqrstuvwxyz0123456789"
}