コンテンツにスキップ

セッション監視

セッション変更にリアルタイムで反応する必要があるアプリケーションのために、@authrim/web はブラウザ側の同期ヘルパーを提供します。対象は、タブ間同期、OIDC OP セッション確認、front-channel logout の検証、低レベルな check_session_iframe 通信です。

機能目的ブラウザ対応
Tab Syncブラウザタブ間の認証状態同期と leader electionBroadcastChannel 対応のモダンブラウザ
Session MonitorOP の check_session_iframe をポーリングして OIDC セッション変更を検知iframe とサードパーティ Cookie の制約を受ける
Front-Channel LogoutOP が iframe で読み込むログアウト要求を検証iframe とブラウザストレージの制約を受ける
Check Session Iframecheck_session_iframe の低レベル postMessage ラッパーiframe とサードパーティ Cookie の制約を受ける

TabSyncManagerBroadcastChannel を使って、セッション変更やログアウトを他のタブに通知します。また、定期処理を 1 つのタブだけで実行したい場合に使える leader election も行います。

import { TabSyncManager } from '@authrim/web';
const tabSync = new TabSyncManager({
channelName: 'authrim-session',
heartbeatIntervalMs: 5000,
leaderTimeoutMs: 15000,
});
tabSync.initialize();
const unsubscribeLeader = tabSync.onLeaderChange((isLeader) => {
if (isLeader) {
console.log('このタブがバックグラウンド確認を担当します');
}
});
// このタブで新しいセッション状態を観測したときにブロードキャストします。
const sessionResponse = await auth.session.get();
tabSync.broadcastSessionChange(sessionResponse.data?.session ?? null);
// ローカル認証状態をクリアしたあと、ログアウトをブロードキャストします。
tabSync.broadcastLogout();
window.addEventListener('beforeunload', () => {
unsubscribeLeader();
tabSync.destroy();
});

互換 eventEmitter を渡した場合、タブ間のセッション変更、ログアウト、leader 変更に対して session:sync が発火します。emitter を渡さない場合でも、onLeaderChange() を使い、認証フロー内で broadcastSessionChange() または broadcastLogout() を明示的に呼べます。

パラメータデフォルト説明
channelNamestring'authrim-session'BroadcastChannel 名
heartbeatIntervalMsnumber5000leader の heartbeat 間隔
leaderTimeoutMsnumber15000別タブが leader を引き継ぐまでの時間
eventEmitterEventEmitter-session:sync イベント用の任意の SDK event emitter

SessionMonitor は OIDC Session Management の RP 側実装です。OP の check_session_iframe を読み込み、現在の session_state を使ってポーリングし、OP がセッション変更を返したときにイベントを発火します。

import { SessionMonitor } from '@authrim/web';
const monitor = new SessionMonitor({
checkSessionIframeUrl: discovery.check_session_iframe,
clientId: 'my-app',
opOrigin: 'https://auth.example.com',
pollInterval: 2000,
maxErrors: 3,
});
const unsubscribe = monitor.on(async (event) => {
if (event.type === 'session:changed') {
await auth.signOut({ logoutScope: 'local' });
window.location.href = '/login';
}
if (event.type === 'session:error') {
console.warn('OIDC セッション確認に失敗しました:', event.error);
}
});
await monitor.start(initialSessionState);
// 再認証に成功したあと、監視対象の session_state を更新します。
monitor.updateSessionState(newSessionState);
window.addEventListener('beforeunload', () => {
monitor.stop();
unsubscribe();
});
パラメータデフォルト説明
checkSessionIframeUrlstring-discovery から取得した OP の check_session_iframe URL
clientIdstring-OAuth client ID
opOriginstring-postMessage 検証に使う期待 OP origin
pollIntervalnumber2000ポーリング間隔(ミリ秒)
maxErrorsnumber3monitor を停止するまでの連続エラー数
タイプ意味
session:changedOP がユーザーセッションの変更を返した
session:unchanged監視中の session_state がまだ有効
session:erroriframe 確認が失敗した、または OP が error を返した
session:stopped手動停止、またはエラー過多により監視が停止した

FrontChannelLogoutHandler は、登録済みの logout URI に配送される OIDC front-channel logout 要求を検証します。通常、OP はこの URI を hidden iframe で読み込み、iss と必要に応じて sid をクエリパラメータとして付与します。

Authrim 管理画面で front-channel logout URI を登録します。

設定
Front-Channel Logout URIhttps://myapp.com/logout/front-channel
Front-Channel Logout Session Requiredsid を検証できる場合は true
import { FrontChannelLogoutHandler } from '@authrim/web';
const handler = new FrontChannelLogoutHandler({
issuer: 'https://auth.example.com',
sessionId: currentSessionId,
requireIss: true,
requireSid: true,
onLogout: async (params) => {
await auth.signOut({ logoutScope: 'local' });
console.log('Front-channel logout を処理しました:', params.sid);
},
});
if (handler.isLogoutRequest()) {
const result = await handler.handleCurrentUrl();
if (!result.success) {
console.warn('不正な front-channel logout 要求:', result.error);
}
}
パラメータデフォルト説明
issuerstring-期待する OP issuer
sessionIdstring-sid 検証に使う現在の session ID
requireIssbooleanfalseiss パラメータを必須にし検証する
requireSidbooleanfalsesid パラメータを必須にし検証する
onLogout(params) => void | Promise<void>-要求の検証成功後に呼ばれる callback

CheckSessionIframeManagerSessionMonitor が内部で使う低レベルラッパーです。ポーリングを自分で制御したい場合に直接利用できます。

import { CheckSessionIframeManager } from '@authrim/web';
const manager = new CheckSessionIframeManager({
checkSessionIframeUrl: 'https://auth.example.com/check-session',
clientId: 'my-app',
opOrigin: 'https://auth.example.com',
timeout: 5000,
});
await manager.initialize();
const result = await manager.checkSession(currentSessionState);
if (result.response === 'changed') {
await auth.signOut({ logoutScope: 'local' });
window.location.href = '/login';
}
manager.destroy();
パラメータデフォルト説明
checkSessionIframeUrlstring-OP の check_session_iframe URL
clientIdstring-OAuth client ID
opOriginstring-message 検証に使う期待 OP origin
timeoutnumber5000iframe load と message response の timeout

実用的なブラウザ構成では、Tab Sync と明示的なセッション確認経路を組み合わせます。

import { TabSyncManager } from '@authrim/web';
const tabSync = new TabSyncManager();
tabSync.initialize();
const stopLeader = tabSync.onLeaderChange((isLeader) => {
if (!isLeader) return;
const timer = window.setInterval(async () => {
const isValid = await auth.session.validate();
if (!isValid) {
await auth.signOut({ logoutScope: 'local' });
tabSync.broadcastLogout();
window.location.href = '/login';
}
}, 60000);
window.addEventListener('beforeunload', () => window.clearInterval(timer), {
once: true,
});
});
window.addEventListener('beforeunload', () => {
stopLeader();
tabSync.destroy();
});

OIDC check_session_iframe を公開しており、アプリセッション検証に加えて OP セッション変更も検知したい場合は SessionMonitor を追加してください。