Google認証

概要説明

Google認証機能は、Googleアカウントを持つユーザーのためのOAuthベースの認証と登録を提供します。既存ユーザーのログインと新規ユーザーの自動登録の両方をサポートし、Firebase認証を活用して安全なトークン検証とユーザー管理を行います。これは従来のメール/パスワード登録を伴わないOAuthベースの認証方法です。

アクティビティ図

flowchart TD
    A[ユーザーがGoogle認証を開始] --> B{ユーザーは存在?}
    B -->|はい| C[Googleログインフロー]
    B -->|いいえ| D[Google登録フロー]
    
    C --> E[Googleトークンの検証]
    E --> F{トークンは有効?}
    F -->|いいえ| G[トークンエラーを返す]
    F -->|はい| H[Google UIDでユーザーを検索]
    H --> I{ユーザーが見つかった?}
    I -->|いいえ| J[登録にリダイレクト]
    I -->|はい| K[ユーザーステータスのチェック]
    K --> L{ユーザーはアクティブ?}
    L -->|いいえ| M[非アクティブエラーを返す]
    L -->|はい| N[セッションとクッキーの作成]
    
    D --> O[Googleトークンの検証]
    O --> P{トークンは有効?}
    P -->|いいえ| Q[トークンエラーを返す]
    P -->|はい| R[ユーザー情報の抽出]
    R --> S[新規ユーザーアカウントの作成]
    S --> T[デフォルトロールの割り当て]
    T --> U[セッションとクッキーの作成]
    
    N --> V[成功レスポンスを返す]
    U --> V
    J --> W[ユーザーが見つからないエラーを返す]
    M --> X[ステータスエラーを返す]
    G --> Y[認証エラーを返す]
    Q --> Y
    
    style A fill:#e1f5fe
    style V fill:#c8e6c9
    style G fill:#ffcdd2
    style J fill:#ffcdd2
    style M fill:#ffcdd2
    style Q fill:#ffcdd2
    style W fill:#ffcdd2
    style X fill:#ffcdd2
    style Y fill:#ffcdd2

シーケンス図

Googleログインフロー

sequenceDiagram
    participant Client
    participant FirebaseController
    participant AuthService
    participant Firebase
    participant Database
    
    Note over Client,Database: Google OAuthログインフロー
    
    rect rgb(200, 255, 200)
    Note right of Client: ハッピーケースフロー
    
    Client->>FirebaseController: POST /api/v1/general/auth/firebase-login
    Note over Client,FirebaseController: Google IDトークン
    
    rect rgb(200, 230, 255)
    Note right of FirebaseController: 入力検証
    FirebaseController->>FirebaseController: リクエストを検証
    end
    
    rect rgb(200, 255, 255)
    Note right of FirebaseController: ビジネスロジック
    FirebaseController->>AuthService: verifyIdToken(token)
    
    AuthService->>Firebase: Googleトークンの検証
    Firebase-->>AuthService: ユーザー情報(uid, email)
    
    AuthService->>Database: UIDでユーザーを検索
    Database-->>AuthService: ユーザーデータ
    
    AuthService->>Database: ユーザーステータスとグループのチェック
    Database-->>AuthService: グループメンバーシップ情報
    end
    
    rect rgb(230, 200, 255)
    Note right of AuthService: セッション作成
    AuthService->>AuthService: createAuthCookieByUser()
    AuthService-->>FirebaseController: ユーザーデータ + クッキー
    end
    
    FirebaseController->>Client: 200 OK + Set-Cookieヘッダー
    end
    
    rect rgb(255, 200, 200)
    Note right of Client: エラーハンドリング
    rect rgb(255, 230, 230)
    alt 無効なトークン
        Firebase-->>AuthService: トークン検証失敗
        AuthService-->>FirebaseController: 認証エラー
        FirebaseController->>Client: 401 Unauthorized
    else ユーザーが見つからない
        Database-->>AuthService: ユーザーが見つからない
        AuthService-->>FirebaseController: ユーザーが見つからない
        FirebaseController->>Client: 404 User Not Found
    else ユーザーが非アクティブ
        Database-->>AuthService: ユーザーが非アクティブ
        AuthService-->>FirebaseController: ユーザーステータスエラー
        FirebaseController->>Client: 403 Forbidden
    end
    end
    end

Google登録フロー

sequenceDiagram
    participant Client
    participant GoogleController
    participant AuthService
    participant Firebase
    participant Database
    
    Note over Client,Database: Google OAuth登録フロー
    
    rect rgb(200, 255, 200)
    Note right of Client: ハッピーケースフロー
    
    Client->>GoogleController: POST /api/v1/general/auth/google/register
    Note over Client,GoogleController: {email, name, companyName}
    
    rect rgb(200, 230, 255)
    Note right of GoogleController: 入力検証
    GoogleController->>GoogleController: リクエストデータを検証
    end
    
    rect rgb(200, 255, 255)
    Note right of GoogleController: ビジネスロジック
    GoogleController->>AuthService: registerByGoogle(email, name, companyName)
    
    AuthService->>Firebase: Googleトークンの検証
    Firebase-->>AuthService: トークン検証済み + ユーザー情報
    
    AuthService->>Database: ユーザーの存在チェック
    Database-->>AuthService: ユーザーが見つからない
    
    AuthService->>Database: Googleデータからユーザーを作成
    Database-->>AuthService: ユーザー作成完了
    
    AuthService->>Database: デフォルトグループロールを割り当て
    Database-->>AuthService: ロール割り当て完了
    end
    
    rect rgb(230, 200, 255)
    Note right of AuthService: セッション作成
    AuthService->>AuthService: createAuthCookieByUser()
    AuthService-->>GoogleController: ユーザーデータ + クッキー
    end
    
    GoogleController->>Client: 201 Created + Set-Cookieヘッダー
    end
    
    rect rgb(255, 200, 200)
    Note right of Client: エラーハンドリング
    rect rgb(255, 230, 230)
    alt 検証エラー
        GoogleController->>Client: 422 Validation Error
    else メール既存
        Database-->>AuthService: メール存在
        AuthService-->>GoogleController: メール競合
        GoogleController->>Client: 409 Conflict
    else 無効なGoogleトークン
        Firebase-->>AuthService: トークン検証失敗
        AuthService-->>GoogleController: 認証エラー
        GoogleController->>Client: 401 Unauthorized
    end
    end
    end

ステップ

Googleログインプロセス

ステップ1: Googleトークンの送信

  • 説明: ユーザーが認証用のGoogle IDトークンを送信
  • リクエスト: POST /api/v1/general/auth/firebase-login
  • ヘッダー: firebase-token: {google_id_token}
  • 検証: トークンの存在と形式

ステップ2: Googleトークンの検証

  • 説明: FirebaseがGoogle IDトークンを検証
  • アクション:
    • トークンをFirebase認証に送信
    • 検証済みユーザー情報(uid, email)を抽出
    • トークンの有効期限と真正性を検証

ステップ3: 既存ユーザーの検索

  • 説明: Firebase UIDでユーザーレコードを特定
  • アクション:
    • 一致するUIDでユーザーのデータベースクエリ
    • ユーザーのグループメンバーシップとロールを読み込み
    • ユーザーアカウントステータスをチェック

ステップ4: 認証セッションの作成

  • 説明: 安全なセッションクッキーを生成
  • アクション:
    • ユーザートークンで認証クッキーを作成
    • ログイン状態クッキーを設定
    • 安全なセッションを確立

Google登録プロセス

ステップ1: 登録データの送信

  • 説明: ユーザーがGoogle認証情報で登録を送信
  • リクエスト: POST /api/v1/general/auth/google/register
  • データ: Googleアカウントからのemail, name, companyName
  • 検証: 必須フィールドと形式

ステップ2: Googleトークンの検証

  • 説明: Google OAuthを通じてユーザーを認証
  • アクション:
    • FirebaseでGoogle IDトークンを検証
    • 検証済みユーザー情報を抽出
    • トークンの真正性を確保

ステップ3: ユーザー存在のチェック

  • 説明: ユーザーが既に登録されていないことを確認
  • アクション:
    • 既存メールのデータベースクエリ
    • ユーザーが既に存在する場合はエラーを返す
    • 新規ユーザーの場合は登録を続行

ステップ4: ユーザーアカウントの作成

  • 説明: Googleデータから新しいユーザーを作成
  • アクション:
    • Googleからのユーザー情報を保存
    • Firebase UIDマッピングを生成
    • アカウントステータスをアクティブに設定

ステップ5: デフォルトロールの割り当て

  • 説明: ユーザーの初期グループメンバーシップを設定
  • アクション:
    • グループメンバーシップレコードの作成
    • デフォルトグループロールの割り当て
    • ユーザー権限の確立

ステップ6: セッションの作成

  • 説明: 新規ユーザーを自動的にログイン
  • アクション:
    • 認証クッキーの生成
    • ログイン状態の作成
    • セッション付きのユーザーデータを返す

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

erDiagram
    users {
        bigint id PK "主キー"
        varchar name "Googleからのユーザーのフルネーム"
        varchar email UK "Googleからのユーザーのメールアドレス"
        varchar uid "Firebase UID(Google認証に必要)"
        varchar payment_provider_customer_id "決済プロバイダーの顧客ID"
        tinyint status "ユーザーステータス(1: アクティブ, 0: 非アクティブ)"
        varchar remember_token "Laravelリメンバートークン"
        timestamp created_at "作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
        timestamp deleted_at "ソフト削除タイムスタンプ"
        boolean is_first_login "初回ログインフラグ"
    }
    
    groups {
        bigint id PK "主キー"
        varchar name "グループ名"
        text description "グループの説明"
        bigint created_by FK "グループを作成したユーザー"
        timestamp created_at "作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }
    
    group_members {
        bigint id PK "主キー"
        bigint group_id FK "グループID"
        bigint user_id FK "ユーザーID"
        bigint group_role_id FK "グループ内のロールID"
        timestamp created_at "作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }
    
    admin_roles {
        bigint id PK "主キー"
        varchar name "管理者ロール名"
        text description "管理者ロールの説明"
        timestamp created_at "作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }
    
    admin_role_user {
        bigint id PK "主キー"
        bigint user_id FK "ユーザーID"
        bigint admin_role_id FK "管理者ロールID"
        timestamp created_at "作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }
    
    sessions {
        varchar id PK "セッションID"
        bigint user_id FK "ユーザーID"
        string ip_address "ユーザーのIPアドレス"
        text user_agent "ユーザーのブラウザエージェント"
        text payload "セッションデータ"
        int last_activity "最終アクティビティタイムスタンプ"
    }
    
    users ||--o{ group_members : "持つ"
    groups ||--o{ group_members : "含む"
    users ||--o{ admin_role_user : "持つ"
    admin_roles ||--o{ admin_role_user : "定義する"
    users ||--o{ sessions : "作成する"
    users ||--o{ groups : "作成する"

APIエンドポイント

Googleログイン

  • URL: POST /api/v1/general/auth/firebase-login
  • ヘッダー:
    • Content-Type: application/json
    • firebase-token: {google_id_token}
  • ボディ: 空または最小限のデータ
  • 目的: 既存のGoogleユーザーの認証

Google登録

  • URL: POST /api/v1/general/auth/google/register
  • ヘッダー: Content-Type: application/json
  • ボディ:
    {
      "email": "user@gmail.com",
      "name": "John Doe",
      "companyName": "Example Corp"
    }
    
  • 目的: Google OAuthを通じて新規ユーザーを登録

エラーハンドリング

HTTPステータス エラーコード 説明
400 VALIDATION_ERROR 無効なリクエストデータまたは必須フィールドの不足
401 UNAUTHORIZED 無効または期限切れのGoogleトークン
404 USER_NOT_FOUND ログイン試行中にユーザーが見つからない
403 USER_INACTIVE ユーザーアカウントが非アクティブ
409 EMAIL_ALREADY_EXISTS 登録中にメールが既に登録済み
500 INTERNAL_SERVER_ERROR 認証プロセス中のサーバーエラー

追加ノート

  • OAuth専用認証: この機能はGoogle OAuth認証のみを処理
  • 標準登録なし: 従来のメール/パスワード登録をサポートしない
  • Firebase統合: 安全なトークン検証にFirebase認証を使用
  • 自動登録: 新規ユーザーは初回ログイン中に自動的に作成
  • セッション管理: 認証成功直後に認証クッキーを作成
  • ロール割り当て: 新規ユーザーは自動的にデフォルトグループロールを受信
  • トークンセキュリティ: Google IDトークンはFirebaseで真正性を検証
  • シームレスな体験: ユーザーはGoogleアカウントを使用して認証
  • UIDマッピング: Firebase UIDはすべてのGoogle認証ユーザーに必要で保存
  • パスワード管理なし: ユーザーはGoogleを通じて認証、パスワード保存は不要