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