サインアウト
Logto(OIDC ベースのアイデンティティプロバイダー)におけるサインアウトプロセスは、Logto が管理する集中型サインインセッションと、クライアントアプリケーションが管理する分散型認証 (Authentication) 状態の両方が関与するため、多面的な概念となっています。
サインインセッション
サインアウトプロセスをよりよく理解するためには、まず Logto でユーザーのサインインセッションとその認証 (Authentication) 状態がどのように管理されているかを理解することが重要です。
- ユーザーが Web アプリケーション(RP)へアクセスします。
- クライアントアプリケーションがユーザーを Logto(IdP)へ 認証 (Authentication) のためリダイレクトします。
- OIDC プロバイダーがユーザーのサインインセッション状態を確認します。セッションが存在しない、または期限切れの場合、ユーザーにサインインを促します。
- ユーザーがサインインページで認証 (Authentication) を行います。
- サインインが成功すると、Logto はユーザーの新しいセッションを作成し、認可コード付きでクライアントアプリケーションへリダイレクトします。
- OIDC プロバイダーがユーザーの新しいサインインセッションと認証 (Authentication) グラントを作成します。
- OIDC プロバイダーが認証 (Authentication) コード付きでユーザーをクライアントへリダイレクトします(認可コードフロー)。
- クライアントが認証 (Authentication) コードを受け取り、トークンと交換します。
- クライアントアプリケーションにトークンを付与します。
コンポーネント
Logto が管理する集中型サインインセッション
上記のフローにおいて、集中型サインインセッションは Logto によって管理されます。ユーザーがサインインに成功するとセッションが作成され、サインアウト時またはセッションの有効期限切れ時に破棄されます。
Logto のサインインセッションはセッションクッキーで管理されます。ユーザーがサインインするとセッションクッキーが設定されます。すべての認証 (Authentication) リクエストはこのセッションクッキーに対して検証されます。セッションクッキーが存在し有効な場合、ユーザーは自動的に認証 (Authentication) され、認可コード付きでクライアントアプリケーションへ直接リダイレクトされます。そうでない場合は、サインインを促されます。
-
共有 Logto セッションクッキー
同じユーザーエージェント(例:ブラウザ)から複数のクライアントアプリケーションにサインインするユーザーは、Logto ドメイン下で共有セッションクッキーを持ちます。つまり、一度サインインすれば他のクライアントアプリケーションでも自動的に認証 (Authentication) されます。 -
分離された Logto セッションクッキー
異なるデバイスやブラウザから異なるクライアントアプリケーションにサインインするユーザーは、Logto ドメイン下で分離されたセッションクッキーを持ちます。つまり、それぞれのクライアントアプリケーションごとに個別にサインインが必要です。
クライアントアプリケーションが管理する分散型認証 (Authentication) 状態
各クライアントアプリケーションは独自に認証 (Authentication) 状態を管理します。ネイティブ、SPA、Web アプリケーションいずれも、ユーザーの認証 (Authentication) 状態を管理する独自の方法を持っています。
サインインが成功すると、クライアントアプリケーションは ID トークン や アクセス トークン を受け取る場合があります。クライアントアプリケーションは ID トークンでユーザーのアイデンティティを判別し、アクセス トークンでユーザーのリソースにアクセスできます。ユーザーの認証 (Authentication) 状態はアクセス トークンの有効期限で表されます。
- ネイティブおよび SPA アプリケーション:
クライアントアプリケーションは、これらのトークンを安全に保存・管理し、ユーザーの認証 (Authentication) 状態を維持する必要があります。例:ローカルストレージやセッションストレージに保存し、サインアウト時にトークンを削除します。 - Web アプリケーション:
Next.js などのフレームワークで構築された Web アプリは、Logto から発行されたトークンと並行して独自のセッションを管理することがよくあります。サインイン後、Web アプリが Logto からトークンを受け取ったら、SPA アプリケーションと同様にクライアント側でトークンを保存するか、サーバー側でトークンを保存し、クッキーや他の仕組みでセッションを管理できます。
サインアウトの仕組み
クライアント側でトークンとローカルセッションをクリア
クライアント側でのシンプルなサインアウトは、ローカルセッションをクリアし、トークン(ID トークン、アクセス トークン、リフレッシュ トークン)をローカルストレージやセッションストレージから削除することです。これはクライアント側のみのサインアウトとなり、集中型セッションはそのまま残ります。この方法でサインアウトしたユーザーは、集中型セッションが期限切れまたは明示的に破棄されるまで、同じ認可サーバーセッション下の他のアプリケーションにアクセスできる場合があります。
Logto でサインインセッションをクリア
ユーザーを明示的にサインアウトし、Logto 側のセッションをクリアするには、クライアントアプリケーションがユーザーを Logto の end session endpoint へリダイレクトする必要があります。
例: https://{your-logto-domain}/oidc/session/end
end session endpoint は、クライアントアプリケーションが認可サーバーにユーザーのサインアウトを通知できる標準 OIDC エンドポイントです。このエンドポイントは Logto 側の集中型サインインセッションをクリアします。
セッションがクリアされると、以降の認可リクエストでは再度サインインが必要となります。
post-logout redirect URI が指定されている場合、セッションがクリアされた後にユーザーは指定された URI へリダイレクトされます。指定がない場合は、Logto がホストするデフォルトのポストログアウトページへリダイレクトされます。
フェデレーテッドサインアウト:バックチャネルログアウト
より一貫したサインアウト管理のために、Logto は バックチャネルログアウト をサポートしています。バックチャネルログアウトは、ユーザーがサインアウトした際に、同じサインインセッション下のすべてのクライアントアプリケーションへ Logto から通知する仕組みです。
これは、ユーザーがあるクライアントアプリケーションからサインアウトし、同じ Logto サインインセッション下の他のすべてのクライアントアプリケーションからもサインアウトされることを期待するシナリオで特に有用です。
クライアントアプリケーションでバックチャネルログアウトを有効にするには、Logto ダッシュボードのアプリケーション詳細ページでバックチャネルログアウト URI を登録してください。ユーザーがいずれかのクライアントアプリケーションからサインアウトリクエストを開始すると、Logto は登録されたすべての URI へログアウトトークンを送信します。
クライアントアプリケーションでサインインセッションをログアウトトークンに含める必要がある場合は、バックチャネルログアウト設定で Is session required
を有効にしてください。ログアウトトークンに sid
クレームが含まれ、Logto でのユーザーのサインインセッションを識別できます。
- ユーザーがいずれかのクライアントアプリケーションからサインアウトリクエストを開始します。
- Logto が end session リクエストを受信し、ログアウトトークンを生成し、登録されたすべてのバックチャネルログアウト URI へ送信します。
- 各クライアントアプリケーションがログアウトトークンを受信し、サインアウト処理を実行します。
各クライアントアプリケーションがログアウトトークンを受信した際のサインアウト処理:
- ログアウトトークンを検証する。
- ローカルセッションをクリアし、ローカルストレージやセッションストレージからトークンを削除する。
Logto SDK におけるサインアウト方法
Logto の SDK を使ってクライアントアプリケーションと連携している場合:
- SPA や Web アプリケーションでは、
client.signOut()
メソッドがローカルトークンストレージをクリアし、ユーザーを Logto の end session endpoint へリダイレクトします。セッションがクリアされた後にユーザーをリダイレクトする post-logout redirect URI を指定できます。 - ネイティブアプリケーション(React Native や Flutter などのハイブリッドアプリを含む)では、ローカルトークンストレージのみがクリアされます。ネイティブアプリケーションでは、サインインプロセスにセッションレス WebView を使用するため、ネイティブブラウザにセッションクッキーが保存されません。そのため、Logto 側のサインインセッションをクリアする必要はありません。各認証 (Authentication) リクエストはセッションクッキーを持たない独立したリクエストとなります。
セッションレス WebView をサポートしない、または emphasized
設定を認識しないネイティブアプリケーション(React Native や Flutter SDK を使用した Android アプリなど)の場合、認可リクエストに prompt=login
パラメータを渡すことで、ユーザーに再度サインインを促すことができます。
毎回再認証 (Authentication) を強制する
高セキュリティなシナリオ(例:機密操作前のユーザー本人確認)では、毎回ユーザーに再認証 (Authentication) を要求したい場合があります。この動作を強制するには、認証 (Authentication) リクエストに prompt=login
を含めてください。
prompt=login
を設定すると、ユーザーがアクティブなセッションを持っているか、最近サインインしたかに関わらず、Logto は必ずサインインページを表示します。これによりシングルサインオン (SSO) の動作をバイパスし、毎回ユーザーに認証情報の入力を促します。
アプリが offline_access スコープ(リフレッシュ トークンを受け取るため)をリクエストする場合、OpenID Connect 仕様により prompt=consent
も含める必要があります。
ほとんどの場合、再認証 (Authentication) を強制し、かつリフレッシュ トークン発行を確実にするには、次のように設定します:
prompt=login consent
これにより、ユーザーは再認証 (Authentication) され、オフラインアクセスへの明示的な同意も行われます。
よくある質問
バックチャネルログアウト通知が届きません
- Logto ダッシュボードでバックチャネルログアウト URI が正しく登録されているか確認してください。
- クライアントアプリケーションに有効なアクティブサインインセッションがあり、サインアウトリクエストを開始したものと同じセッションであることを確認してください。
関連リソース
OIDC バックチャネルログアウトの理解