代理ログイン
概要説明
代理ログイン機能により、管理者はサポートやトラブルシューティング目的でグループメンバーのアイデンティティを一時的に引き受けることができます。この機能によって、管理者は特定のユーザーがアプリケーションをどのように見るかを正確に確認でき、より効果的なサポートと問題解決が可能になります。管理者がこの機能を使用する際、システムと対話しながら選択したユーザーであるかのように振る舞うことができますが、管理者のコンテキストは維持されます。
アクティビティ図
---
config:
theme: base
layout: dagre
flowchart:
curve: linear
htmlLabels: true
themeVariables:
edgeLabelBackground: "transparent"
---
flowchart TB
%% Main components
AdminUser[管理者ユーザー]
AdminDashboard[管理者ダッシュボード]
Database[(データベース)]
%% 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 --> SelectGroup[グループ/ユーザー選択]
SelectGroup --- 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 --> SendRequest[代理ログインリクエスト送信]
SendRequest --- 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 --> GroupIDCheck{有効なグループID?}
GroupIDCheck -->|いいえ| Step4A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4A</span>
<p style='margin-top: 8px'>エラー返却</p>
</div>
]
Step4A --> ReturnError[エラー返却]
GroupIDCheck -->|はい| Step4B[
<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'>4B</span>
<p style='margin-top: 8px'>ステータス確認</p>
</div>
]
Step4B --> CheckStatus[グループステータス確認]
CheckStatus --> Database
CheckStatus --- 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'>アクティブ確認</p>
</div>
]
Step5 --> GroupActiveCheck{グループアクティブ?}
GroupActiveCheck -->|いいえ| Step6A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6A</span>
<p style='margin-top: 8px'>エラー返却</p>
</div>
]
Step6A --> ReturnError
GroupActiveCheck -->|はい| Step6B[
<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'>6B</span>
<p style='margin-top: 8px'>作成者検索</p>
</div>
]
Step6B --> FindCreator[グループ作成者検索]
FindCreator --> Database
FindCreator --- 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 --> CreatorCheck{作成者あり?}
CreatorCheck -->|いいえ| Step8A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8A</span>
<p style='margin-top: 8px'>エラー返却</p>
</div>
]
Step8A --> ReturnError
CreatorCheck -->|はい| Step8B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8B</span>
<p style='margin-top: 8px'>セッション作成</p>
</div>
]
Step8B --> CreateSession[代理セッション作成]
CreateSession --- Step9[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>9</span>
<p style='margin-top: 8px'>Cookie設定</p>
</div>
]
Step9 --> SetCookie[代理Cookie設定]
SetCookie --- Step10[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>10</span>
<p style='margin-top: 8px'>データ返却</p>
</div>
]
Step10 --> ReturnData[作成者コンテキスト付きユーザーデータ返却]
ReturnData --- Step11[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>11</span>
<p style='margin-top: 8px'>ユーザーとして閲覧</p>
</div>
]
Step11 --> UserView[ユーザーとしてアプリケーション閲覧]
UserView --- Step12[
<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'>12</span>
<p style='margin-top: 8px'>戻る確認</p>
</div>
]
Step12 --> ReturnCheck{管理者に戻る?}
ReturnCheck -->|はい、ID=0| Step13A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>13A</span>
<p style='margin-top: 8px'>セッションクリア</p>
</div>
]
Step13A --> ClearSession[代理セッションクリア]
ClearSession --- Step14[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>14</span>
<p style='margin-top: 8px'>管理者に戻る</p>
</div>
]
Step14 --> ReturnAdmin[管理者コンテキストに戻る]
ReturnAdmin --- Step15[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>15</span>
<p style='margin-top: 8px'>ダッシュボードに戻る</p>
</div>
]
Step15 --> AdminDashboard
ReturnCheck -->|いいえ、継続| Step13B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>13B</span>
<p style='margin-top: 8px'>セッション継続</p>
</div>
]
Step13B --> UserView
%% Styling
style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style AdminDashboard fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style SelectGroup fill:#f0f8e6,stroke:#339933,stroke-width:2px
style SendRequest fill:#f0f8e6,stroke:#339933,stroke-width:2px
style GroupIDCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style CheckStatus fill:#f0f8e6,stroke:#339933,stroke-width:2px
style GroupActiveCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style FindCreator fill:#f0f8e6,stroke:#339933,stroke-width:2px
style CreatorCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style CreateSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style SetCookie fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnData fill:#f0f8e6,stroke:#339933,stroke-width:2px
style UserView fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style ClearSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnAdmin fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnError fill:#fcd9d9,stroke:#cc3333,stroke-width:2px
style Database fill:#ffe6cc,stroke:#ff9900,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 Step4A fill:transparent,stroke:transparent,stroke-width:1px
style Step4B fill:transparent,stroke:transparent,stroke-width:1px
style Step5 fill:transparent,stroke:transparent,stroke-width:1px
style Step6A fill:transparent,stroke:transparent,stroke-width:1px
style Step6B fill:transparent,stroke:transparent,stroke-width:1px
style Step7 fill:transparent,stroke:transparent,stroke-width:1px
style Step8A fill:transparent,stroke:transparent,stroke-width:1px
style Step8B fill:transparent,stroke:transparent,stroke-width:1px
style Step9 fill:transparent,stroke:transparent,stroke-width:1px
style Step10 fill:transparent,stroke:transparent,stroke-width:1px
style Step11 fill:transparent,stroke:transparent,stroke-width:1px
style Step12 fill:transparent,stroke:transparent,stroke-width:1px
style Step13A fill:transparent,stroke:transparent,stroke-width:1px
style Step13B fill:transparent,stroke:transparent,stroke-width:1px
style Step14 fill:transparent,stroke:transparent,stroke-width:1px
style Step15 fill:transparent,stroke:transparent,stroke-width:1px
API: 代理ログインAPI
ケースドキュメント
ケース1: 代理ログイン成功
説明
管理者がグループメンバーの代理として正常にログインします。
シーケンス図
sequenceDiagram
participant Admin as 管理者
participant API as 代理ログインコントローラー
participant Service as 認証サービス
participant GroupService
participant DB as データベース
Note over Admin,API: ステップ1: 代理リクエスト送信
Admin->>API: PATCH /api/v1/admin/auth/representative/{id}
Note over API,API: ステップ2: 管理者認証確認
API->>API: 管理者が認証済みか確認
Note over API,GroupService: ステップ3: グループ読込
API->>GroupService: getById(id)
GroupService->>DB: グループ検索
DB-->>GroupService: グループデータ返却
Note over API,API: ステップ4: グループステータス確認
API->>API: グループがアクティブか確認
Note over API,Service: ステップ5: 代理セッション作成
API->>Service: createRepresentative(group.creator)
Service->>Service: 認証Cookie生成
Note over API,Admin: ステップ6: レスポンス返却
API-->>Admin: 200 OK (作成者データと代理Cookie)
ステップ
ステップ1: 代理リクエスト送信
- 説明: 管理者がグループの代理として行動するリクエストを送信
- リクエスト:
PATCH /api/v1/admin/auth/representative/{id} - URLパラメータ:
- id: 代理するグループのID (必須)
- 認証:
- 管理者が既に認証済みである必要がある
ステップ2: 管理者認証確認
- 説明: システムが管理者が認証済みであることを確認
- アクション:
- ユーザーがログインしているか確認
- 認証状態を確認
- 潜在的エラー:
- 認証チェック失敗 (403 禁止)
ステップ3: グループ読込
- 説明: システムがリクエストされたグループを取得
- アクション:
- IDでグループを取得するためのグループサービス呼び出し
- 作成者リレーションシップを持つグループをロード
- 潜在的エラー:
- グループが見つからない
ステップ4: グループステータス確認
- 説明: グループがアクティブで代理可能であることを確認
- アクション:
- グループステータスがアクティブであることを確認
- グループに作成者が割り当てられていることを確認
- 潜在的エラー:
- グループが非アクティブ (403 禁止)
ステップ5: 代理セッション作成
- 説明: グループ作成者として行動するためのセッション作成
- アクション:
- 代理セッションを作成する認証サービスの呼び出し
- 代理コンテキスト用の認証Cookie生成
- 代理フラグをtrueに設定
ステップ6: レスポンス返却
- 説明: 代理セッションで成功レスポンスを送信
- レスポンス:
- 成功:
200 OK(作成者ユーザーデータ付き) - 代理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 "ソフト削除タイムスタンプ"
}
groups {
id bigint "主キー"
name string "グループ名"
created_by bigint "usersテーブルへの参照"
status int "グループステータス (0: 非アクティブ, 1: アクティブ)"
created_at timestamp "レコード作成タイムスタンプ"
updated_at timestamp "レコード最終更新タイムスタンプ"
}
group_members {
id bigint "主キー"
user_id bigint "usersテーブルへの参照"
group_id bigint "groupsテーブルへの参照"
group_role_id bigint "group_rolesテーブルへの参照"
is_creator boolean "グループ作成者フラグ"
joined_at timestamp "メンバー参加タイムスタンプ"
created_at timestamp "レコード作成タイムスタンプ"
updated_at timestamp "レコード最終更新タイムスタンプ"
}
group_roles {
id bigint "主キー"
name string "ロール名"
slug string "ロールスラッグ"
created_at timestamp "レコード作成タイムスタンプ"
updated_at timestamp "レコード最終更新タイムスタンプ"
}
users ||--o{ group_members : has
groups ||--o{ group_members : has
group_roles ||--o{ group_members : has
エラー処理
-
ログ
- 代理ログイン失敗を記録
- グループステータスの問題を記録
-
エラー詳細:
コード メッセージ 説明 401 "ログイン情報が正しくありません。" 管理者ロールにユーザーが見つからない場合 401 "認証情報と一致するレコードがありません。" ログインに失敗した場合 401 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" 予期しないエラーが発生した場合
ケース2: 管理者アカウントに戻る
説明
代理管理者が元の管理者アカウントに戻ります。
シーケンス図
sequenceDiagram
participant Admin as 管理者
participant API as 代理ログインコントローラー
participant Auth
participant Cookie
Admin->>API: PATCH /api/v1/admin/auth/representative/0
API->>Auth: 現在のユーザーを取得
Auth-->>API: 管理者ユーザーを返却
API->>Cookie: forget(representative)
API-->>Admin: 200 OK (管理者ユーザーデータ)
ステップ
ステップ1: 戻りリクエスト送信
- 説明: 管理者が管理者アカウントに戻るリクエストを送信
- リクエスト:
PATCH /api/v1/admin/auth/representative/0 - URLパラメータ:
- id: 0 (管理者に戻ることを示す特別な値)
ステップ2: 代理フラグリセット
- 説明: システムが代理ステータスをクリア
- アクション:
- 代理フラグをfalseに設定
- 変更なしで現在の管理者ユーザーを使用
ステップ3: 代理Cookieクリア
- 説明: 代理コンテキストCookieを削除
- アクション:
- 代理Cookie用の「忘れる」Cookieを作成
- 過去の有効期限でCookieを設定
ステップ4: レスポンス返却
- 説明: 管理者コンテキストを復元
- レスポンス:
- 成功:
200 OK(管理者ユーザーデータ付き) - Cookieクリア指示を含める
- 成功:
追加事項
- 代理ログイン機能は、管理者の実際のアイデンティティと代理ユーザーの間に明確な区別を維持します
- システムはCookieを使用して代理状態を追跡します
- 代理として行動している場合、特定の管理機能が制限される場合があります
- 管理者モードに戻るのは管理者機能を完全に復元する簡単なプロセスです
- グループ作成者のみが代理可能で、任意のグループメンバーではありません