Open2

認証・認可についての雑多なメモ

宇野礼於宇野礼於

JWTトークンのペイロードの生成例

import jwt
import datetime

# 秘密鍵(署名に使用)
SECRET_KEY = "your-secret-key"

# ペイロードの作成
payload = {
    "iss": "example.com",  # 発行者
    "sub": "1234567890",   # 対象ユーザーID
    "aud": "example-app",  # トークンの利用者
    "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1),  # 有効期限 (1時間後)
    "nbf": datetime.datetime.utcnow(),  # トークン有効開始時間
    "iat": datetime.datetime.utcnow(),  # 発行時間
    "jti": "unique-token-id",  # トークンの一意識別子
    "username": "john.doe",    # ユーザー名
    "role": "admin"            # ユーザーの権限
}

# JWTトークンの生成
token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")

print("Generated JWT Token:")
print(token)

jtiは、トークンの利用回数を制限するために使うもの。
トークン生成時にUUIDなどでランダム値を入れておき、それをredisなどインメモリDBで管理。
トークンが使われるたびにカウントすることで、利用回数を制限できる。

逆に、有効期限内なら何回でも使える設計にするならjtiは不要。

宇野礼於宇野礼於

FastAPI
セッションログインの実装方法についてのメモ

secrets.token_urlsafe(32)

などで256ビット(32バイト)ぐらいのランダム文字列にする。
セッションIDにはユーザー情報などは含めず、十分な長さのランダム文字列が適切。
これをRedisかDBに保存。

DBテーブルは以下のような感じ。

class LoginSession(SQLModel):
    id: str  # セッションID
    user_id: str
    expires_at: datetime

cookieにはセッションIDを設定。
そのほか、クッキーの属性として、httponly, samesite: laxかstrict, secure, max_ageを設定する。