セッション切れ再認証
昼休みに切れたセッションが、それを発見したクリックまで食べてしまう
べきではありません。このレシピでは、保護されたアクションの 401 が
共有ホストへ retarget されたログイン <dialog> を運びます —
installRemoteDialog
(出荷済み)がそれを開きます。そして自動インストールされる
installSessionExpiry() が中断されたリクエストを覚えていて、ログイン
応答が hc:sessionrenewed を発火した瞬間に再実行します。ユーザーの
操作は消えずに完了します。
バージョニングポリシーの
対象です。
別名: セッションタイムアウト、再ログイン。
デモのセッションは切れた状態から始まります: Approve をクリックし、
サインインして(どのパスワードでも可、wrong はインラインエラー)、
承認がひとりでに完了するのを見てください。Expire session で
フローを再武装できます。
The session starts expired — click Approve.
マークアップ
Section titled “マークアップ”<button class="hc-button" data-variant="primary" type="button" data-hx-post="/tickets/7/approve" data-hx-target="#status" data-hx-swap="innerHTML"> Approve</button><p class="hc-field__hint" id="status" aria-live="polite"></p>
<!-- body 末尾の共有ホスト 1 つ --><div id="error-dialog" data-hc-remote-dialog-root data-hc-session-expiry></div>ホストは 2 つの帽子をかぶります: data-hc-remote-dialog-root は
サーバーがスワップしてきたダイアログを開き、data-hc-session-expiry
はリプレイブリッジを武装します。
サーバー応答契約
Section titled “サーバー応答契約”| ケース | 応答 |
|---|---|
| 保護されたエンドポイント、セッション切れ、htmx リクエスト | 401 + HX-Retarget: #error-dialog + HX-Reswap: innerHTML + ログインダイアログのフラグメント。サーバーは処理の前に 401 しなければなりません — リプレイの安全性はそこに依存します |
| ログイン成功 | 200 + 空ボディ + HX-Trigger: {"hc:sessionrenewed": {}} — ブリッジがダイアログを閉じてリプレイします |
| ログイン失敗 | 422 + HX-Retarget: #error-dialog + HX-Reswap: innerHTML + field-errors をインラインに再描画したダイアログ — ログインフォームは data-hx-target="this" / data-hx-swap="none" で POST するため、ヘッダーがなければボディは飲み込まれます |
| 非 htmx リクエストでのセッション切れ | ?next= 付きログインページへの 303 |
リプレイの意味論
Section titled “リプレイの意味論”スロットは 1 つ、最新が勝ちます: 並行して中断された場合は最後の
1 件だけがリプレイされます。リプレイは
htmx.ajax(verb, path, { source, values }) を通り、通常の
パイプラインを再走します — ローテートされた CSRF トークンは
installCsrfHeader が毎リクエスト読み直し、インジケーターも
ターゲットも、ユーザーがもう一度クリックしたかのように振る舞います。
複数値フィールドは最後の値に畳まれます。中断された要素が DOM を
離れていればリプレイはスキップされます。ページロードをまたいで
何も生き残りません。
アクセシビリティ
Section titled “アクセシビリティ”- ダイアログは
showModal()による本物の<dialog>です — ネイティブの フォーカストラップとEscape。aria-labelledbyが名前を与えます。 - Cancel は
<form method="dialog">のボタン — 宣言的で CSP 安全です。 - リプレイの結果はアクション自身の
aria-liveターゲットに着地する ため、完了が読み上げられます。
- edit-conflict — 同じエラーダイアログホストに乗る 409 の姉妹レシピ。
- エラーとリカバリー — ステータスコードの地図と統合された許可。
- remote-dialog — このレシピが乗るホスト機構。
- field-errors — このレシピが 401 へ拡張する 422 許可の形。