SSO 認証フロー — 中央会員管理 & SSO ハブ
1. ドキュメントの目的
このドキュメントは、会員がさまざまな SaaS アプリにアクセスするために使用する Single Sign-On (SSO) のフローを説明します。
2. アクター
- 会員
- SaaS アプリ (例: NOTO)
- 会員管理ハブ (SSO プロバイダー)
3. SSO の基本概念
会員ログイン
│
▼
会員管理ハブ (SSO プロバイダー)
│── アカウント & ライセンスの検証
│
▼
JWT トークンが発行される
│
▼
SaaS アプリがトークンを受け取る
│── トークンの検証
│── メンバー ID、階層、製品、有効期限の読み取り
│
▼
会員がアプリのダッシュボードにログインする
4. 会員のログインフロー
4.1 技術的なステップ
- 会員が SaaS アプリを開く (例:
app.noto.com). - 会員が ログイン ボタンをクリックする。
- SaaS アプリが
stateパラメーター (セキュリティのための CSRF) を作成し、暫定的に保存する。 - SaaS アプリが会員管理ハブのログインエンドポイントにリダイレクトする:
https://hub.domain.com/oauth/authorize ?client_id=[APP_CLIENT_ID] &redirect_uri=[CALLBACK_URL_APLIKASI] &response_type=code &state=[RANDOM_STATE] &scope=profile:read license:read - 会員がハブのログインページでメールアドレスとパスワードを入力する。
- ハブが会員の:
- 認証情報を検証する
- アカウントのステータス (
active) を検証する - ライセンスの有効性を検証する
- 有効であれば、ハブがアプリに 認可コード をリダイレクトする:
https://callback.noto.com/auth/callback ?code=[AUTH_CODE] &state=[RANDOM_STATE] - SaaS アプリが
stateを検証して CSRF を防ぐ。 - SaaS アプリがハブに
codeを送信する (バックエンドからバックエンドのリクエスト):POST https://hub.domain.com/oauth/token Body: { client_id, client_secret, code, redirect_uri, grant_type: "authorization_code" } - ハブが JWT アクセストークンを返す:
{ "access_token": "eyJhbGci...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "..." } - SaaS アプリが JWT の内容を読み取り検証する:
{ "sub": "member_id", "name": "会員名", "email": "email@会員.com", "product": "NTO", "license_id": "NTO-A1B2-C3D4-E5F6", "tier": "free", "license_status": "active_free", "expires_at": null, "iat": 1720000000, "exp": 1720003600 } - SaaS アプリがローカルセッションを作成する。
- 会員がアプリのダッシュボードにログインする。
5. リフレッシュトークンのフロー
アクセストークンが期限切れになったとき:
- SaaS アプリがリフレッシュトークンをハブに送信する。
- ハブがリフレッシュトークンとライセンスのステータスを検証する。
- ライセンスが有効であれば、ハブが新しいアクセストークンを発行する。
- ライセンスが無効または凍結であれば、ハブがエラー
license_inactiveを返す。 - SaaS アプリが会員をリフレッシュトークンページにリダイレクトする。
6. ログアウトのフロー
- 会員がアプリのログアウトボタンをクリックする。
- SaaS アプリがローカルセッションとトークンを削除する。
- SaaS アプリがオプションでハブのログアウトエンドポイントにリダイレクトする:
https://hub.domain.com/oauth/logout ?post_logout_redirect_uri=[ログアウト後のページ] - ハブが会員のハブセッションを終了する。
- 会員が指定されたページにリダイレクトされる。
7. JWT トークンのフィールド
| フィールド | タイプ | 説明 |
|---|---|---|
sub |
string | 会員のユニークID |
name |
string | 会員の名前 |
email |
string | 会員のメールアドレス |
product |
string | SaaS アプリの製品コード |
license_id |
string | 会員のライセンスID |
tier |
string | 有効な階層 (free, pro, business) |
license_status |
string | ライセンスのステータス (active, active_free, grace_period, suspended) |
expires_at |
タイムスタンプ / null | ライセンスの期限切れ日時 (null なら永久有効) |
iat |
タイムスタンプ | トークンの発行日時 |
exp |
タイムスタンプ | トークンの期限切れ日時 |
8. アプリのトークン検証方法
アプリはハブの パブリックキー (RS256) を使用して JWT を検証する。
- アプリがパブリックキーを取得する:
GET https://hub.domain.com/.well-known/jwks.json - アプリがトークンの署名をパブリックキーで検証する。
- アプリがトークンの期限切れを検証する。
- アプリが製品コードがアプリのコードと一致するかを検証する。
- アプリがライセンスステータスが
active,active_free, またはgrace_periodであるかを検証する。 - すべての条件が満たされれば、会員がアプリにログインできる。
9. エラー条件と対応
| エラー条件 | ハブのレスポンス | アプリの対応 |
|---|---|---|
| 認証情報が不正 | 401 invalid_credentials |
ログインエラーを表示する |
| アカウントが未確認 | 403 email_not_verified |
未確認アカウントページにリダイレクトする |
| アカウントが非アクティブ | 403 account_suspended |
サポートチームに連絡する |
| ライセンスが無効 | 403 no_license |
ライセンス選択ページにリダイレクトする |
| ライセンスが凍結 | 403 license_suspended |
ライセンス更新ページにリダイレクトする |
| トークンが期限切れ | 401 token_expired |
リフレッシュトークンを取得する |
| リフレッシュトークンが無効 | 401 invalid_refresh_token |
ログインページにリダイレクトする |
10. SSO のセキュリティ
- JWT は RS256 (非対称) アルゴリズムで署名される。
- 秘密鍵はハブのサーバーにのみ保存される。
- パブリックキーはアプリが検証に使用できる。
- アクセストークンは短期間有効 (例: 1 時間)。
- リフレッシュトークンは長期間有効 (例: 30 日)。
- State パラメーターは CSRF を防ぐために使用される。
- 全ての通信は HTTPS で行われる。
- アプリは会員の認証情報 (パスワード) を保存してはならない。
11. 新規 SaaS アプリの統合
新規 SaaS アプリがエコシステムに参加するには:
- ハブに OAuth2 クライアントとして登録する。
client_idとclient_secretを取得する。 3.許可されたredirect_uriを登録する。