認証/認可設計ガイド
認証(Authentication)と認可(Authorization)のフレームワーク非依存な設計ガイド。
認証と認可の区別
code
認証 (AuthN): 「誰であるか」を確認する → ログイン、トークン検証、MFA 認可 (AuthZ): 「何ができるか」を判断する → 権限チェック、リソースアクセス制御
認証方式の選択
| 方式 | 適用場面 | 特徴 |
|---|---|---|
| セッションベース | 従来型 Web アプリ、SSR | サーバーで状態管理、Cookie で識別 |
| トークンベース (JWT) | SPA、モバイル、マイクロサービス | ステートレス、署名で検証 |
| パスキー / WebAuthn | セキュリティ重視のアプリ | フィッシング耐性、UX 良好 |
| API キー | サーバー間通信、外部 API | シンプル、ユーザー認証には不向き |
選択判断フロー
code
ブラウザベースの Web アプリ?
├→ SSR(サーバーサイドレンダリング)→ セッションベース
└→ SPA(クライアントレンダリング)→ トークンベース
├→ BFF パターン採用?→ セッション + BFF でトークン管理
└→ BFF なし → HttpOnly Cookie に JWT を保存
モバイルアプリ?→ トークンベース(セキュアストレージに保存)
サーバー間通信?→ API キー or OAuth Client Credentials
認証フロー設計
ログインフロー
code
1. クライアント → 認証情報送信(email + password) 2. サーバー → 認証情報検証 3. サーバー → セッション/トークン発行 4. クライアント → セッション/トークン保存 5. 以降のリクエスト → セッション/トークンを付与
登録フロー
code
1. 入力バリデーション(形式、一意性) 2. パスワードハッシュ化(bcrypt / Argon2) 3. ユーザー作成 4. メール確認(必要に応じて) 5. 自動ログイン or ログインページへ
パスワードリセット
code
1. メールアドレス入力(ユーザー存在の有無を漏らさない) 2. リセットトークン生成(十分なエントロピー、有効期限あり) 3. リセット用リンクをメール送信 4. トークン検証 → 新パスワード設定 5. 既存セッション/トークンを無効化
MFA(多要素認証)
code
認証要素の種類: - 知識: パスワード、PIN - 所持: TOTP アプリ、SMS、ハードウェアキー - 生体: 指紋、顔認証 推奨: TOTP > SMS(SMS は SIM スワップリスクあり) フロー: 1. 第1要素の認証成功 2. MFA チャレンジの発行 3. 第2要素の検証 4. 認証完了、セッション/トークン発行
認可モデル
RBAC(ロールベースアクセス制御)
code
構造: ユーザー → ロール → 権限 例: admin → [users:read, users:write, users:delete, settings:write] editor → [users:read, content:read, content:write] viewer → [users:read, content:read] 適用場面: - 権限が明確にグループ化できる - ロール数が限定的(10個以下が目安)
ABAC(属性ベースアクセス制御)
code
構造: ポリシー = 主体属性 + リソース属性 + 環境属性 + アクション 例: 「部門マネージャーは、自部門のメンバーのデータのみ編集可能」 → 主体.role == "manager" AND リソース.department == 主体.department 適用場面: - 複雑な条件が必要(組織、時間、場所など) - RBAC では表現しきれない細かい制御
リソースベースアクセス制御
code
構造: リソースの所有者/メンバーが操作可能 例: - 自分のプロフィールのみ編集可能 - プロジェクトメンバーのみアクセス可能 実装: 1. リソース取得 2. リクエスト者とリソースの関係を検証 3. アクセス可否を判定
詳細: references/authorization-models.md
トークン管理
JWT 設計原則
code
ペイロードに含めるもの: - sub: ユーザー ID - exp: 有効期限 - iat: 発行時刻 - iss: 発行者 - aud: 対象者 - roles/permissions: 権限情報(最小限) 含めてはいけないもの: - パスワード - 個人情報(メール、住所等) - 大量のデータ(トークンサイズが増大)
リフレッシュトークン戦略
code
アクセストークン: 短い有効期限(15分〜1時間) リフレッシュトークン: 長い有効期限(7日〜30日) リフレッシュフロー: 1. アクセストークン期限切れ 2. リフレッシュトークンで新しいアクセストークンを取得 3. リフレッシュトークンもローテーション(推奨) 保存場所: - Web: HttpOnly + Secure + SameSite Cookie - モバイル: セキュアストレージ - ❌ localStorage / sessionStorage(XSS リスク)
セッション管理
code
設計原則: - 十分なエントロピーのセッション ID - HttpOnly + Secure + SameSite Cookie - 適切な有効期限(アクティブ/非アクティブ) - ログアウト時のサーバーサイド無効化 - セッション固定攻撃対策(認証後に再生成) - 同時セッション数の制限(必要に応じて)
OAuth / OpenID Connect
code
Authorization Code Flow(推奨): 1. クライアント → 認可サーバーにリダイレクト 2. ユーザー → 認証 + 同意 3. 認可サーバー → Authorization Code を返却 4. クライアント(サーバーサイド)→ Code でトークン交換 5. アクセストークン + ID トークン取得 PKCE(Proof Key for Code Exchange): - SPA / モバイルアプリでは必須 - Authorization Code Flow + PKCE 使い分け: - Authorization Code + PKCE: Web アプリ、モバイル - Client Credentials: サーバー間通信(ユーザー不在) - ❌ Implicit Flow: 非推奨(セキュリティリスク)
API 認証
| 方式 | 用途 | 実装 |
|---|---|---|
| Bearer Token | ユーザー認証済み API | Authorization: Bearer {token} |
| API Key | 外部開発者向け API | ヘッダー or クエリパラメータ |
| mTLS | サーバー間の相互認証 | クライアント証明書 |
認証エラーハンドリング
code
原則: - 認証失敗の理由を詳細に返さない ❌ "パスワードが間違っています" ❌ "ユーザーが存在しません" ✅ "認証情報が正しくありません" - レート制限でブルートフォースを防止 - アカウントロックアウトのポリシーを設定 - 認証試行をログに記録
レビューチェックリスト
- • パスワードが安全にハッシュ化されている
- • トークン/セッションに適切な有効期限がある
- • リフレッシュトークンがローテーションされている
- • 認証失敗時に情報漏洩がない
- • すべてのエンドポイントで認可チェックがある
- • 水平/垂直権限昇格が防止されている
- • CSRF 対策が実装されている
- • MFA が重要操作に対して提供されている
リファレンス
- •references/auth-flows.md - 認証フロー詳細と実装パターン
- •references/authorization-models.md - 認可モデル詳細と選択基準