ユーザーログアウト

概要説明

ユーザーログアウト機能は、ユーザーセッションを安全に終了させ、認証Cookieをクリーンアップします。システムは通常のログアウトプロセスと、失敗時のセッションフラッシュ(フォールバック)メカニズムの両方をサポートしています。

アクティビティ図

flowchart TD
    A[ユーザーがログアウトを要求] --> B{ユーザーは認証済み?}
    B -->|いいえ| C[認証エラーを返す]
    B -->|はい| D[セッションの検証]
    D --> E{セッションは有効?}
    E -->|いいえ| F[セッション無効エラーを返す]
    E -->|はい| G[ログアウト処理の開始]
    
    G --> H[メインセッションの無効化]
    H --> I{セッション削除は成功?}
    I -->|はい| J[代理セッションの無効化]
    I -->|いいえ| K[セッションフラッシュを実行]
    
    J --> L{代理セッション削除は成功?}
    L -->|はい| M[認証Cookieの削除]
    L -->|いいえ| K
    
    K --> N[すべてのセッションデータを強制削除]
    M --> O[レスポンスCookieの設定]
    N --> O
    
    O --> P[成功レスポンスを返す]
    
    style A fill:#e1f5fe
    style P fill:#c8e6c9
    style C fill:#ffcdd2
    style F fill:#ffcdd2
    style K fill:#ffcdd2

シーケンス図

ログアウト成功

sequenceDiagram
    participant User
    participant API as LogoutController
    participant Auth as AuthService
    participant Session as SessionDB
    participant Cookie as CookieManager

    Note over User,API: ステップ1: ログアウト開始
    User->>API: GET /api/v1/general/auth/logout
    
    Note over API,Auth: ステップ2: ログアウト処理
    API->>Auth: logout()
    
    Note over Auth,Session: ステップ3: メインセッションの無効化
    Auth->>Session: セッションレコードを削除
    Session-->>Auth: 削除確認
    
    Note over Auth,Session: ステップ4: 代理セッションの無効化
    Auth->>Session: 代理セッションを削除
    Session-->>Auth: 削除確認
    
    Note over Auth,Cookie: ステップ5: 認証Cookieの削除
    Auth->>Cookie: forget(auth_api_token)
    Auth->>Cookie: forget(is_logged_in)
    Auth->>Cookie: forget(representative)
    
    Note over API,User: ステップ6: レスポンス返却
    API-->>User: 200 OKと削除されたCookie

セッションフラッシュ(フォールバック)

sequenceDiagram
    participant User
    participant API as LogoutController
    participant Session as SessionDB

    User->>API: GET /api/v1/general/auth/logout
    API->>API: 通常のログアウトを試行
    Note over API: 例外が発生
    API->>Session: flush()
    API-->>User: 401 Unauthorized

ステップ

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

  • 説明: ユーザーがアプリケーションからログアウトを要求
  • リクエスト: GET /api/v1/general/auth/logout
  • ヘッダー:
    • 認証Cookieが自動的に含まれる
  • 検証:
    • ユーザーが認証済みかチェック
    • セッションが存在するか検証

ステップ2: ログアウト処理

  • 説明: コントローラーがログアウトプロセスを開始
  • アクション:
    • Authファサードのlogoutメソッドを呼び出し
    • メインセッションと代理セッションの両方を処理
    • Cookie削除の準備

ステップ3: メインセッションの無効化

  • 説明: ユーザーのメイン認証セッションを削除
  • アクション:
    • データベースからセッションレコードを削除
    • 認証済みユーザーリストからユーザーを削除
    • セッショントークンを無効化
    • セッション終了をログに記録

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

  • 説明: 代理セッションが存在する場合は削除
  • アクション:
    • アクティブな代理セッションをチェック
    • 代理セッションレコードを削除
    • 代理コンテキストを削除
    • 代理セッション終了をログに記録

ステップ5: 認証Cookieの削除

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

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

  • 説明: Cookie削除の指示を含む成功レスポンスを送信
  • レスポンス:
    • 成功: 200 OKと成功メッセージ
    • レスポンスにCookie削除の指示を含める
    • ブラウザ用に正しくフォーマットされたCookie削除ヘッダー

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

erDiagram
    sessions {
        bigint id PK
        string session_id "一意のセッション識別子"
        bigint user_id FK "usersテーブルへの参照"
        string guard_name "認証ガード名"
        string ip_address "クライアントのIPアドレス"
        string user_agent "クライアントのユーザーエージェント"
        text payload "セッションデータ"
        timestamp last_activity "最終アクティビティタイムスタンプ"
        timestamp created_at
        timestamp updated_at
    }
    users {
        bigint id PK
        string name "ユーザーのフルネーム"
        string email "ユーザーのメールアドレス(一意)"
        string status "アカウントステータス: active, inactive, suspended"
        timestamp created_at
        timestamp updated_at
    }

    sessions }o--|| users : "属する"

エラーハンドリング

  • ログ記録

    • ログアウトエラーはアプリケーションログに記録
    • 例外の詳細はデバッグ用に記録
    • (オプション)セキュリティイベント用のSlackメッセージ送信
  • エラー詳細:

    ステータスコード エラーメッセージ 説明
    401 "セッションが無効です。" セッションが無効な場合
    401 "ログアウトに失敗しました。" ログアウトが失敗した場合
    401 例外メッセージを含む一般エラー 予期しないエラーが発生した場合

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

説明

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

シーケンス図

sequenceDiagram
    participant User
    participant API as LogoutController
    participant Session as SessionDB

    User->>API: GET /api/v1/general/auth/logout
    API->>API: 通常のログアウトを試行
    Note over API: 例外が発生
    API->>Session: flush()
    API-->>User: 401 Unauthorized

ステップ

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

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

ステップ2: 例外処理

  • 説明: ログアウトプロセス中の例外をキャッチして処理
  • アクション:
    • try/catchブロックで例外をキャッチ
    • 例外の詳細をログに記録
    • (オプション)Slack通知を送信

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

  • 説明: すべてのセッションデータを強制削除
  • アクション:
    • セッションフラッシュメソッドを呼び出し
    • ユーザーのすべてのセッションレコードを削除
    • 関連するすべてのCookieを削除
    • 緊急フラッシュイベントをログに記録

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

  • 説明: クライアントにログアウト問題を通知
  • レスポンス:
    • エラー: 401 Unauthorizedと例外メッセージ
    • Cookie削除の指示を含める

追加メモ

  • レート制限: ログアウト試行はIPアドレスごとに1分間に10回に制限
  • ログアウトは異なるタイプのユーザー(管理者、一般、代理)で一貫して動作するように設計
  • Cookieは設定に基づいてドメイン固有
  • システムは予期されるログアウトと予期しないログアウトの両方のシナリオを処理
  • セッションフラッシュは通常のログアウトが失敗した場合のセキュリティ確保の最終手段として使用
  • ログアウト後、ユーザーは通常クライアントアプリケーションによってログインページにリダイレクトされる
  • セキュリティ監視のためのセッションアクティビティ追跡の実装を検討中