管理者ログアウト

概要説明

管理者ログアウト機能は、アプリケーション内の管理ユーザーセッションを終了するための安全なメカニズムを提供します。管理者がログアウトすると、システムは認証トークンを無効化し、セッションデータをクリアし、ブラウザから認証Cookieを削除します。このプロセスは通常の管理者セッションと特殊な代理セッションの両方を処理し、セキュリティ目的ですべての認証痕跡の完全な削除を保証します。

アクティビティ図

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    %% Main components
    AdminUser[管理者ユーザー]
    
    %% Process steps with numbering
    AdminUser --- Step1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>ログアウト開始</p>
        </div>
    ]
    Step1 --> SendRequest[ログアウトリクエスト送信]
    
    SendRequest --- Step2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>リクエスト処理</p>
        </div>
    ]
    Step2 --> ProcessRequest[サーバーがログアウト処理]
    
    ProcessRequest --- Step3[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
            <p style='margin-top: 8px'>セッション無効化</p>
        </div>
    ]
    Step3 --> InvalidateSession[管理者セッション無効化]
    
    InvalidateSession --- Step4[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4</span>
            <p style='margin-top: 8px'>代理クリア</p>
        </div>
    ]
    Step4 --> ClearRepresentative[代理セッション無効化]
    
    ClearRepresentative --- Step5[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5</span>
            <p style='margin-top: 8px'>Cookieクリア</p>
        </div>
    ]
    Step5 --> ClearCookies[認証Cookieクリア]
    
    ClearCookies --- Step6[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6</span>
            <p style='margin-top: 8px'>代理Cookieクリア</p>
        </div>
    ]
    Step6 --> ClearRepCookies[代理Cookieクリア]
    
    ClearRepCookies --- Step7[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7</span>
            <p style='margin-top: 8px'>状態クリア</p>
        </div>
    ]
    Step7 --> ClearState[状態Cookieクリア]
    
    ClearState --- Step8[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8</span>
            <p style='margin-top: 8px'>レスポンス返却</p>
        </div>
    ]
    Step8 --> ReturnResponse[成功レスポンス返却]
    
    ReturnResponse --- Step9[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>9</span>
            <p style='margin-top: 8px'>リダイレクト</p>
        </div>
    ]
    Step9 --> Redirect[ログインページにリダイレクト]
    
    %% Styling
    style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style SendRequest fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ProcessRequest fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style InvalidateSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ClearRepresentative fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ClearCookies fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ClearRepCookies fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ClearState fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ReturnResponse fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style Redirect fill:#f0f8e6,stroke:#339933,stroke-width:2px
    
    style Step1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step3 fill:transparent,stroke:transparent,stroke-width:1px
    style Step4 fill:transparent,stroke:transparent,stroke-width:1px
    style Step5 fill:transparent,stroke:transparent,stroke-width:1px
    style Step6 fill:transparent,stroke:transparent,stroke-width:1px
    style Step7 fill:transparent,stroke:transparent,stroke-width:1px
    style Step8 fill:transparent,stroke:transparent,stroke-width:1px
    style Step9 fill:transparent,stroke:transparent,stroke-width:1px

API: 管理者ログアウトAPI

ケースドキュメント

ケース1: 管理者ログアウト成功

説明

管理者がアプリケーションから正常にログアウトし、すべてのセッションデータがクリアされます。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ログアウトコントローラー
    participant Auth as 認証サービス
    participant Cookie as Cookieサービス

    Note over Admin,API: ステップ1: ログアウト開始
    Admin->>API: GET /api/v1/admin/auth/logout
    
    Note over API,Auth: ステップ2: 管理者セッション無効化
    API->>Auth: logout()
    Auth->>Auth: メインセッション無効化
    
    Note over API,Auth: ステップ3: 代理セッション無効化
    API->>Auth: logout('representative')
    Auth->>Auth: 代理セッション無効化
    
    Note over API,Cookie: ステップ4: 認証Cookie削除
    API->>Cookie: forget(auth_api_token)
    API->>Cookie: forget(is_logged_in)
    API->>Cookie: forget(representative)
    
    Note over API,Admin: ステップ5: レスポンス返却
    API-->>Admin: 200 OK (Cookieクリア済み)

ステップ

ステップ1: ログアウト開始

  • 説明: 管理者がアプリケーションからログアウトをリクエスト
  • リクエスト: GET /api/v1/admin/auth/logout
  • ヘッダー:
    • 認証Cookieが自動的に含まれる

ステップ2: 管理者セッション無効化

  • 説明: メイン管理者認証セッションをクリア
  • アクション:
    • Authファサードのlogoutメソッドを呼び出し
    • 認証済みユーザーリストから管理者を削除
    • セッショントークンを無効化

ステップ3: 代理セッション無効化

  • 説明: 存在する場合は代理セッションをクリア
  • アクション:
    • 代理ガード上でAuthファサードのlogoutメソッドを呼び出し
    • アクティブな場合は代理コンテキストを削除

ステップ4: 認証Cookieクリア

  • 説明: クライアントからすべての認証Cookieを削除
  • アクション:
    • 以下の「忘れる」Cookie インスタンスを作成:
      • 認証APIトークンCookie
      • ログイン状態Cookie
      • 代理Cookie
    • Cookieの有効期限を過去の日付に設定
    • 元のCookieと同じドメイン/パスを使用していることを確認

ステップ5: レスポンス返却

  • 説明: Cookie削除指示付きの成功レスポンスを送信
  • レスポンス:
    • 成功: 成功メッセージ付きの200 OK
    • Cookie削除指示をレスポンスに添付
    • ブラウザ用に適切にフォーマットされたCookieクリアヘッダー

エラー処理

  • ログ

    • ログアウトエラーはアプリケーションログに記録
    • デバッグ用に例外詳細を記録
  • エラー詳細:

    ステータスコード エラーメッセージ 説明
    401 例外メッセージを含む一般的なエラー ログアウト中に予期しないエラーが発生した場合

ケース2: セッションフラッシュ (フォールバック)

説明

通常のログアウトが失敗した場合、セッションデータが確実にクリアされるようにセッションフラッシュが実行されます。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ログアウトコントローラー
    participant Session

    Admin->>API: GET /api/v1/admin/auth/logout
    API->>API: 通常のログアウトを試行
    Note over API: 例外発生
    API->>Session: flush()
    API-->>Admin: 401 未認証 (エラーメッセージ付き)

ステップ

ステップ1: 通常のログアウト試行

  • 説明: システムが標準的なログアウト手順を試行
  • アクション: 成功ケースと同じ

ステップ2: 例外処理

  • 説明: ログアウト中の例外をキャッチして処理
  • アクション:
    • try/catchブロックで例外をキャッチ
    • 例外詳細をログに記録

ステップ3: 緊急フラッシュ

  • 説明: すべてのセッションデータを強制的にクリア
  • アクション:
    • セッションフラッシュメソッドを呼び出し
    • すべてのセッションデータが削除されていることを確認

ステップ4: エラーレスポンス

  • 説明: ログアウトの問題をクライアントに通知
  • レスポンス:
    • エラー: 例外メッセージ付きの401 未認証

追加事項

  • ログアウトは、管理者が標準モードまたは代理モードのいずれにあるかにかかわらず、一貫して機能するように設計されています
  • Cookieは設定に従ってドメイン固有です
  • システムは予期されるログアウトシナリオと予期しないログアウトシナリオの両方を処理します
  • 通常のログアウトが失敗した場合、最後の手段としてセキュリティを確保するためにセッションフラッシングが使用されます
  • ログアウト後、管理者は通常クライアントアプリケーションによってログインページにリダイレクトされます

関連するデータベーステーブルとフィールド

erDiagram
    users {
        id bigint "主キー"
        name string "ユーザーのフルネーム"
        email string "ユーザーのメールアドレス (ユニーク)"
        uid string "Firebase UID (ユニーク)"
        payment_provider_customer_id string "決済プロバイダーの顧客ID (nullable)"
        status int "アカウントステータス (0: 非アクティブ, 1: アクティブ)"
        is_first_login int "初回ログインフラグ (0: まだ, 1: ログイン済)"
        remember_token string "記憶トークン"
        created_at timestamp "レコード作成タイムスタンプ"
        updated_at timestamp "レコード最終更新タイムスタンプ"
        deleted_at timestamp "ソフト削除タイムスタンプ"
    }
    admin_roles {
        id bigint "主キー"
        name string "ロール名"
        slug string "ロールスラッグ"
        created_at timestamp "レコード作成タイムスタンプ"
        updated_at timestamp "レコード最終更新タイムスタンプ"
    }
    admin_role_user {
        admin_role_id bigint "admin_rolesテーブルへの参照"
        user_id bigint "usersテーブルへの参照"
        created_at timestamp "レコード作成タイムスタンプ"
        updated_at timestamp "レコード最終更新タイムスタンプ"
    }

    users ||--o{ admin_role_user : has
    admin_roles ||--o{ admin_role_user : has