第4部:認証機能 Step 11 / 24

認証の基礎

認証(Authentication)は「誰がアクセスしているか」を確認する仕組み。JWT(JSON Web Token)を使った現代的な認証方式を学びます。

認証と認可の違い

認証(Authentication)

「あなたは誰ですか?」を確認

  • ・ログイン処理
  • ・ユーザーIDの特定
  • ・パスワード/トークン検証

認可(Authorization)

「あなたは何ができますか?」を確認

  • ・アクセス権限チェック
  • ・自分の記事のみ編集可能
  • ・管理者のみ削除可能

認証方式の比較

方式 特徴 用途
セッション サーバーに状態を保持、Cookieで管理 従来のWebアプリ
JWT トークンに情報を含む、ステートレス SPA、モバイル、API
OAuth 2.0 外部サービスで認証(Google, GitHub等) ソーシャルログイン

このコースでは:APIに適したJWT認証を実装します。

JWT(JSON Web Token)とは

JWTの構造

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3MDU0MTIwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header: アルゴリズム情報

Payload: ユーザー情報、有効期限など

Signature: 改ざん検知用の署名

Payloadの例

{
  "user_id": 1,
  "email": "user@example.com",
  "exp": 1705412000,  // 有効期限
  "iat": 1705325600   // 発行日時
}

JWT認証のフロー

1

ログインリクエスト

クライアント → サーバー: email, password を送信

2

認証処理

サーバー: パスワードをハッシュと照合、JWTを生成

3

トークン返却

サーバー → クライアント: JWTトークンを返す

4

トークン保存

クライアント: トークンをlocalStorageに保存

5

認証が必要なリクエスト

クライアント → サーバー: Authorizationヘッダーにトークンを付与

Authorization: Bearer eyJhbGciOiJ...
6

トークン検証

サーバー: 署名を検証、有効期限を確認、ユーザー情報を取得

パスワードのハッシュ化

絶対にやってはいけないこと:パスワードを平文(そのまま)でデータベースに保存しない!

bcryptでハッシュ化

from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# ハッシュ化(登録時)
password = "user_password"
hashed = pwd_context.hash(password)
# → "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"

# 検証(ログイン時)
pwd_context.verify(password, hashed)  # True
pwd_context.verify("wrong_password", hashed)  # False

bcryptは同じパスワードでも毎回異なるハッシュを生成(ソルト付き)

セキュリティの注意点

SECRET_KEYを公開しない

JWTの署名に使う秘密鍵は環境変数で管理、Gitにコミットしない

トークンの有効期限を短くする

アクセストークンは15分〜1時間程度。リフレッシュトークンで更新

HTTPSを使用する

トークンが盗聴されないよう、本番環境では必ずHTTPS

XSS対策

localStorageに保存したトークンはXSS攻撃で盗まれる可能性。httpOnly Cookieの検討も

まとめ

  • 認証は「誰か」を確認、認可は「何ができるか」を確認
  • JWTはステートレスでAPI向きの認証方式
  • パスワードは必ずbcryptでハッシュ化
  • SECRET_KEYは絶対に公開しない
マイグレーション 次へ:FastAPIで認証