サインアウト
Logto(OIDC ベースのアイデンティティプロバイダー)におけるサインアウトプロセスは、Logto が管理する集中型サインインセッションと、クライアントアプリケーションが管理する分散型認証 (Authentication) 状態の両方が関与するため、多面的な概念となっています。
サインインセッション
サインアウトプロセスをよりよく理解するためには、まず Logto でユーザーのサインインセッションとその認証 (Authentication) 状態がどのように管理されているかを理解することが重要です。
- ユーザーが Web アプリケーション(RP)へアクセスします。
- クライアントアプリケーションはユーザーを Logto(IdP)へ 認証 (Authentication) のためリダイレクトします。
- OIDC プロバイダーがユーザーのサインインセッション状態を確認します。セッションが存在しない、または期限切れの場合、ユーザーにサインインを促します。
- ユーザーがサインインページで認証 (Authentication) を行います。
- サインインが成功すると、Logto はユーザーの新しいセッションを作成し、認可コード付きでクライアントアプリケーションへリダイレクトします。
- OIDC プロバイダーはユーザーの新しいサインインセッションと認証 (Authentication) グラントを作成します。
- OIDC プロバイダーは認証コード付きでユーザーをクライアントへリダイレクトします(認可コードフロー)。
- クライアントは認証コードを受け取り、ユーザー情報へアクセスするためにトークンと交換します。
- クライアントアプリケーションにトークンを付与します。
コンポーネント
Logto が管理する集中型サインインセッション
上記のフローにおいて、集中型サインインセッションは Logto によって管理されます。ユーザーがサインインに成功したときにセッションが作成され、サインアウト時またはセッションの有効期限切れ時に破棄されます。
Logto のサインインセッションはセッションクッキーで管理されます。ユーザーがサインインするとセッションクッキーが設定されます。すべての認証 (Authentication) リクエストはこのセッションクッキーに対して検証されます。セッションクッキーが存在し有効であれば、ユーザーは自動的に認証 (Authentication) され、認可コード付きでクライアントアプリケーションへ直接リダイレクトされます。そうでなければ、サインインを促されます。
-
共有 Logto セッションクッキー
同じユーザーエージェント(例:ブラウザ)から複数のクライアントアプリケーションにサインインするユーザーは、Logto ドメイン下で共有セッションクッキーを持ちます。つまり、一度サインインすれば、他のクライアントアプリケーションでも自動的に認証 (Authentication) されます。 -
分離された Logto セッションクッキー
異なるデバイスやブラウザから異なるクライアントアプリケーションにサインインするユーザーは、Logto ドメイン下で分離されたセッションクッキーを持ちます。つまり、それぞれのクライアントアプリケーションごとに個別にサインインする必要があります。
クライアントアプリケーションが管理する分散型認証 (Authentication) 状態
各クライアントアプリケーションは独自に認証 (Authentication) 状態を管理します。ネイティブ、SPA、Web アプリケーションのいずれであっても、ユーザーの認証 (Authentication) 状態の管理方法はそれぞれ異なります。
サインインが成功すると、クライアントアプリケーションは ID トークン (ID token) や アクセス トークン (Access token) を受け取る場合があります。クライアントアプリケーションは ID トークンでユーザーのアイデンティティを判別し、アクセス トークンでユーザーのリソースへアクセスできます。ユーザーの認証 (Authentication) 状態はアクセス トークンの有効期限で表されます。
- ネイティブおよび SPA アプリケーション:
クライアントアプリケーションは、ユーザーの認証 (Authentication) 状態を維持するため、これらのトークンを安全に保存・管理する必要があります。例:ローカルストレージやセッションストレージに保存し、サインアウト時にトークンを削除します。 - Web アプリケーション:
Next.js などのフレームワークで構築された Web アプリは、Logto から発行されたトークンと並行して独自のセッションを管理することがよくあります。サインイン後、Logto からトークンを受け取った Web アプリは、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 バックチャネルログアウトの理解