Hosted Login vs Embedded Login — 認証ページはどちらが提供すべきか
認証ページを認証基盤側でホストする(Hosted Login)か、各プロダクトに埋め込む(Embedded Login)か。セキュリティ、SSO、UX、運用コストの観点で比較する。
はじめに
自社で OIDC Provider を運営するとき、「ログイン画面をどこに置くか」は重要な設計判断です。
選択肢は 2 つ:
- Hosted Login — 認証基盤がログインページを丸ごと提供する。プロダクトはリダイレクトするだけ
- Embedded Login — 各プロダクトがログインフォームを自前で持ち、バックエンドで認証 API を叩く
結論から言うと、Hosted Login が正解です。この記事ではその理由を整理します。
Hosted Login の動き
プロダクト A (cases.example.com)
│ 「ログイン」ボタン押下
│
│ リダイレクト
▼
認証基盤 (auth.example.com/oidc/authorize)
┌──────────────────────────┐
│ auth.example.com │
│ │
│ メール: [ ] │
│ パスワード: [ ] │
│ │
│ [Google でログイン] │
│ │
│ [ログイン] │
└──────────────────────────┘
│ 認証成功
│
│ 認可コードで戻る
▼
プロダクト A (cases.example.com/callback?code=xxx)
│ コードをトークンに交換
▼
ログイン完了
プロダクトはログイン UI を一切持ちません。ユーザーは一旦 auth.example.com に移動し、認証後にプロダクトに戻ってきます。
Embedded Login の動き
プロダクト A (cases.example.com)
┌──────────────────────────┐
│ cases.example.com │
│ │
│ メール: [ ] │
│ パスワード: [ ] │
│ │
│ [ログイン] │
└──────────────────────────┘
│ パスワードをバックエンドに送信
│
│ バックエンド → 認証 API (auth.example.com/auth/login)
│ → トークン取得
▼
ログイン完了
プロダクトがログインフォームを持ち、パスワードを受け取って認証 API に送信します。
比較
| 観点 | Hosted Login | Embedded Login |
|---|---|---|
| パスワードの経路 | 認証基盤にしか送られない | プロダクトを経由する |
| SSO | 自然に実現(認証基盤の cookie) | 実現困難 |
| プロダクト側の実装 | リダイレクトするだけ | ログインフォーム + API 呼び出し |
| UI の一貫性 | 全プロダクトで同じログイン画面 | プロダクトごとにバラバラ |
| UI のカスタマイズ | 認証基盤側で管理 | プロダクトが自由に変更可能 |
| ログイン UI の更新 | 1 箇所で全プロダクトに反映 | 各プロダクトで個別対応 |
| UX | リダイレクトが入る | シームレス |
| MFA 対応 | 認証基盤が一括対応 | 各プロダクトで実装が必要 |
| セキュリティ監査 | 認証基盤だけ監査すればよい | 全プロダクトを監査する必要あり |
Hosted Login を選ぶべき理由
1. パスワードがプロダクトを通らない
Embedded Login では、ユーザーのパスワードがプロダクトのフロントエンド → バックエンドを経由します。
Embedded: ユーザー → プロダクトA → 認証API
↑
プロダクトAがパスワードを見れる
これは以下のリスクを生みます:
- プロダクトのログにパスワードが残る可能性
- プロダクトの XSS 脆弱性でパスワードが漏洩する可能性
- プロダクトの開発者がパスワードを盗める(信頼の問題)
Hosted Login なら、パスワードは auth.example.com にしか送られません。プロダクトが受け取るのは認可コードだけです。
2. SSO が自然に動く
Hosted Login では、認証基盤のドメイン(auth.example.com)にセッション cookie が保存されます。
1. プロダクト A にログイン → auth.example.com にセッション cookie が作られる
2. プロダクト B にアクセス → auth.example.com にリダイレクト
3. セッション cookie があるのでログイン画面スキップ → 即座に認可コード発行
4. プロダクト B に戻る → ログイン完了(ユーザーはログイン画面を見ていない)
Embedded Login でこれを実現するには、各プロダクトが認証基盤のセッション状態を確認する仕組み(hidden iframe や silent authentication)が必要になり、複雑さが大幅に増します。
3. MFA の追加が 1 箇所で済む
将来 MFA(TOTP、WebAuthn 等)を追加するとき:
- Hosted Login: 認証基盤のログインページに MFA ステップを追加するだけ。全プロダクトに即反映
- Embedded Login: 各プロダクトのログインフォームに MFA UI を追加する必要がある。MFA の種類が増えるたびに全プロダクトを更新
4. セキュリティ監査のスコープが小さい
認証に関するセキュリティ監査(SOC 2、ISO 27001 等)を受ける場合:
- Hosted Login:
auth.example.comだけを監査すればよい - Embedded Login: パスワードを扱う全プロダクトが監査対象になる
5. OAuth 2.0 / OIDC の標準に沿っている
Authorization Code Flow は本来、ユーザーを認可サーバーにリダイレクトして認証する設計です。Embedded Login で Resource Owner Password Grant を使うのは OAuth の設計意図に反しており、OAuth 2.1 で正式に廃止されます。
Hosted Login の弱点と対策
弱点 1: リダイレクトの UX
ユーザーがプロダクトのドメインから一旦離れるのは、UX として若干の違和感があります。
対策:
- ログインページのデザインを統一ブランドにする(「〇〇 にログイン」ではなく「〇〇 アカウントでログイン」)
- SSO が効いている場合はリダイレクトが一瞬で終わるので、ほとんど気にならない
- Auth0、Google、GitHub など主要サービスは全てこの方式であり、ユーザーは慣れている
弱点 2: カスタマイズの制限
ログインページのデザインを各プロダクトに合わせたい場合、認証基盤側で対応する必要があります。
対策:
- クエリパラメータでテーマを切り替える(
?theme=cases→ プロダクト A 用のスタイル) - ロゴ、カラー、文言をクライアント登録時に設定できるようにする
- CSS カスタマイズ用のエンドポイントを提供する
GET /oidc/authorize?client_id=cases-app&theme=cases
→ Cases プロダクト用のデザインでログイン画面を表示
弱点 3: 認証基盤がダウンすると全停止
これは Hosted Login 特有の問題ではなく、認証基盤に依存するすべての設計で同じです。認証基盤の高可用性は前提条件です。
Embedded Login が許容されるケース
| ケース | 理由 |
|---|---|
| ネイティブモバイルアプリ | OS が提供する WebView / Custom Tabs で Hosted Login を表示するのが標準だが、独自 UI を求められることもある |
| レガシーシステムの移行期 | 既存のログインフォームを維持しながら段階的に Hosted Login に移行 |
| ファーストパーティの 1 プロダクトのみ | SSO が不要で、認証基盤とプロダクトが同一チームの場合 |
ただし、これらのケースでも 将来的に Hosted Login に移行する前提 で設計しておくのが望ましいです。
主要サービスの選択
| サービス | 方式 |
|---|---|
| Hosted Login(accounts.google.com) | |
| GitHub | Hosted Login(github.com/login/oauth) |
| Auth0 | Hosted Login(Universal Login を推奨) |
| Firebase Auth | 両方(Hosted 推奨) |
| Cognito | Hosted UI あり(カスタマイズ制限あり) |
| Okta | Hosted Login(Sign-In Widget も提供) |
ほぼすべてのサービスが Hosted Login を推奨しています。
ログインページの品質
Hosted Login を採用するなら、ログインページの品質が全プロダクトの第一印象を決めます。最低限押さえるべきポイント:
| 項目 | 内容 |
|---|---|
| レスポンシブ | モバイル・タブレットで崩れない |
| 高速 | 3 秒以内にインタラクティブ |
| アクセシビリティ | キーボード操作、スクリーンリーダー対応 |
| エラーメッセージ | 「メールアドレスまたはパスワードが正しくありません」(どちらが間違いかは言わない) |
| ブランディング | 会社ロゴ、統一カラー |
| 多言語 | 日本語・英語(最低限) |
| ソーシャルログインボタン | Google 等のボタンデザインガイドラインに準拠 |
まとめ
- Hosted Login(認証基盤がログインページを丸ごと提供)が正解
- パスワードがプロダクトを通らない、SSO が自然に動く、MFA 追加が 1 箇所で済む
- リダイレクトの UX は SSO が効いていればほぼ気にならない
- カスタマイズはテーマ機能やクライアント別設定で対応
- Auth0、Google、GitHub 等の主要サービスもすべてこの方式
- Embedded Login は Resource Owner Password Grant を使うことになり、OAuth 2.1 で廃止予定