ユーザーログイン
概要説明
ユーザーログイン機能により、登録済みユーザーはメールアドレスとFirebaseトークンを使用してシステムに認証できます。システムはFirebaseトークンを検証し、ユーザーのステータスとグループメンバーシップをチェックしてから、セッションを作成し、認証クッキーを返します。
アクティビティ図
flowchart TD
A[クライアントがログインリクエストを送信] --> B[リクエストデータを検証]
B --> C{データは有効?}
C -->|いいえ| D[検証エラーを返す]
C -->|はい| E[Firebaseトークンを検証]
E --> F{トークンは有効?}
F -->|いいえ| G[認証エラーを返す]
F -->|はい| H[UIDでユーザーを検索]
H --> I{ユーザーは存在?}
I -->|いいえ| J[ユーザーが見つからないエラーを返す]
I -->|はい| K[ユーザーステータスをチェック]
K --> L{ユーザーはアクティブ?}
L -->|いいえ| M[非アクティブユーザーエラーを返す]
L -->|はい| N[グループメンバーシップをチェック]
N --> O{ユーザーはグループに所属?}
O -->|いいえ| P[グループなしエラーを返す]
O -->|はい| Q[認証クッキーを作成]
Q --> R[成功レスポンスを返す]
style A fill:#e1f5fe
style R fill:#c8e6c9
style D fill:#ffcdd2
style G fill:#ffcdd2
style J fill:#ffcdd2
style M fill:#ffcdd2
style P fill:#ffcdd2
シーケンス図
ログイン成功
sequenceDiagram
participant Client
participant LoginController
participant AuthService
participant Firebase
participant Database
Client->>LoginController: POST /api/v1/general/auth/login
Note over Client,LoginController: {email, firebase-token header}
LoginController->>LoginController: リクエストを検証
LoginController->>AuthService: login(email, firebaseToken)
AuthService->>Firebase: verifyIdToken(firebaseToken)
Firebase-->>AuthService: ユーザー情報 (uid, email)
AuthService->>Database: UIDでユーザーを検索
Database-->>AuthService: ユーザーデータ
AuthService->>Database: ユーザーステータスとグループをチェック
Database-->>AuthService: グループメンバーシップ情報
AuthService->>AuthService: createAuthCookieByUser()
AuthService-->>LoginController: ユーザーデータ + クッキー
LoginController->>Client: 200 OK + Set-Cookie headers
ログイン失敗
sequenceDiagram
participant Client
participant LoginController
participant AuthService
participant Firebase
Client->>LoginController: POST /api/v1/general/auth/login
Note over Client,LoginController: 無効または期限切れのトークン
LoginController->>LoginController: リクエストを検証
LoginController->>AuthService: login(email, firebaseToken)
AuthService->>Firebase: verifyIdToken(firebaseToken)
Firebase-->>AuthService: 無効なトークンエラー
AuthService-->>LoginController: 認証失敗
LoginController->>Client: 401 Unauthorized
ステップ
ステップ1: リクエスト検証
入力:
- リクエストボディからのメールアドレス
firebase-tokenヘッダーからのFirebaseトークン
ステップ2: Firebaseトークン検証
プロセス:
- ヘッダーからFirebase IDトークンを抽出
- Firebase認証サービスにトークンを送信
- トークンの真正性と有効期限を検証
- ユーザー情報を抽出 (UID, メール, プロバイダー)
ステップ3: ユーザー検索
取得されるユーザーデータ:
- ユーザーID, 名前, メール, ステータス
- グループメンバーシップ
- サブスクリプション情報
- アカウント作成日
ステップ4: ステータスチェック
ユーザーステータス検証:
- usersテーブルの
statusフィールドをチェック - 有効なステータス:
1(アクティブ),0(非アクティブ) - アカウント停止の追加チェック
ステップ5: グループメンバーシップ
要件:
- ユーザーは少なくとも1つのアクティブなグループに所属している必要がある
- グループは
status = 1(アクティブ) である必要がある - ユーザーは有効なロール割り当てが必要
ステップ6: セッション作成
保存されるセッションデータ:
- ユーザーIDと認証トークン
- IPアドレスとユーザーエージェント
- ログインタイムスタンプ
- セッション有効期限
ステップ7: レスポンス生成
HTTPヘッダー:
Set-Cookie: auth_token=...; HttpOnly; Secure; SameSite=LaxSet-Cookie: logged_in=true; HttpOnly; Secure; SameSite=LaxContent-Type: application/json
エラー処理サマリー
| ステップ | エラーコード | HTTPステータス | 説明 |
|---|---|---|---|
| 1 | VALIDATION_ERROR | 400 | 無効なメールまたはトークン不足 |
| 2 | UNAUTHORIZED | 401 | 無効/期限切れのFirebaseトークン |
| 3 | USER_NOT_FOUND | 404 | データベースにユーザーが存在しない |
| 4 | USER_INACTIVE | 403 | ユーザーアカウントが無効化されている |
| 5 | NO_GROUP_MEMBERSHIP | 403 | ユーザーがどのグループにも割り当てられていない |
| 6-7 | INTERNAL_SERVER_ERROR | 500 | セッション作成中のサーバーエラー |
パフォーマンス考慮事項
- データベースインデックス:
uid,email,statusフィールドのインデックス - キャッシュ: グループとサブスクリプションデータを5分間キャッシュ
- コネクションプーリング: データベース接続を効率的に再利用
- 非同期操作: Firebase検証をユーザー検索と並行して実行
- レート制限: ブルートフォース攻撃を防止 (IPあたり5回/分)
詳細なCookie
認証Cookie
1. 認証APIトークンCookie
Set-Cookie: Trend-Viewer_auth_api_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...;
HttpOnly;
Secure;
SameSite=Lax;
プロパティ:
- Name:
Trend-Viewer_auth_api_token({app_name}は設定からのアプリケーション名) - Value: エンコードされたJWTトークン
- HttpOnly:
true(JavaScriptからアクセス不可) - Secure:
true(HTTPS経由でのみ送信) - SameSite:
Lax(CSRF保護)
2. ログイン状態Cookie
Set-Cookie: Trend-Viewer_is_logged_in=true;
HttpOnly;
Secure;
SameSite=Lax;
プロパティ:
- Name:
Trend-Viewer_is_logged_in - Value:
true - HttpOnly:
true - Secure: `true**
- SameSite:
Lax