履歴の暗号化

ユーザーが認証され、サイト上の特権情報を閲覧した後にログアウトするシナリオを想像してください。その後、戻るボタンを押すと、window の履歴状態に保存されている特権情報を引き続き閲覧できてしまいます。これはセキュリティ上のリスクです。これを防ぐために、Inertia.js には履歴の暗号化機能が用意されています。

仕組み

Inertia にアプリの履歴を暗号化するよう指示すると、ブラウザに組み込まれている crypto API を使用して、現在のページデータを履歴状態に push する前に暗号化します。対応するキーはブラウザのセッションストレージに保存されます。ユーザーがページに戻ると、セッションストレージに保存されているキーを使ってデータを復号します。

Inertia に履歴状態をクリアするよう指示すると、セッションストレージ内の既存のキーを削除し、新しいキーを生成します。新しいキーで履歴状態の復号を試みると失敗するため、Inertia はページデータを取得するためにサーバーへ新しいリクエストを送信します。

履歴の暗号化は window.crypto.subtle に依存しており、これはセキュアな環境(SSL が有効なサイト)でのみ利用可能です。

有効化(オプトイン)

履歴の暗号化はオプトイン機能です。有効化する方法はいくつかあります。

グローバル暗号化

履歴の暗号化をグローバルに有効にしたい場合は、inertia.history.encrypt の設定値を true に設定します。

特定のページで暗号化を無効にしたい場合は、レスポンスを返す前に Inertia::encryptHistory() メソッドを呼び出します。

php
Inertia::encryptHistory(false);

リクエスト単位の暗号化

個々のリクエストの履歴を暗号化するには、レスポンスを返す前に Inertia::encryptHistory() メソッドを呼び出すだけです。

php
Inertia::encryptHistory();

暗号化ミドルウェア

特定のルートグループを暗号化するには、Inertia に同梱されている EncryptHistory ミドルウェアを使用できます。

php
Route::middleware([Inertia\Middleware\EncryptHistory::class])->get('/', function() {
    //
});

Route::middleware(['inertia::encrypt'])->get('/', function() {
    //
});

履歴のクリア

履歴状態をクリアするには、レスポンスを返す前に Inertia::clearHistory() メソッドを呼び出します。

php
Inertia::clearHistory();

クライアントでレスポンスがレンダリングされると、暗号化キーがローテーションされ、以前の履歴状態は読み取れなくなります。

また、クライアント側で router.clearHistory() を呼び出すことで履歴をクリアすることもできます。