CSRF 保護
リクエストの作成
Laravel は、Inertia や Axios を介してリクエストを行う際に、適切な CSRF トークンを自動的に含めます。ただし、Laravel を使用している場合は、プロジェクトから csrf-token の meta タグを必ず削除してください。これが存在すると、CSRF トークンが正しく更新されなくなります。
サーバーサイドのフレームワークにクロスサイトリクエストフォージェリ(CSRF)保護が含まれている場合、POST、PUT、PATCH、DELETE リクエストに対して、各 Inertia リクエストに必要な CSRF トークンが含まれていることを確認する必要があります。
もちろん、すでに説明したとおり、Laravel などの一部のサーバーサイドフレームワークでは、リクエスト時に CSRF トークンの追加が自動的に処理されます。そのため、これらのフレームワークを使用している場合、追加の設定は不要です。
しかし、CSRF 保護を手動で処理する必要がある場合の一つの方法は、すべてのレスポンスに CSRF トークンを props として含めることです。その後、Inertia リクエストを行う際にそのトークンを使用できます。
また、Inertia の 共有データ 機能を使用して、各レスポンスに csrf_token を自動的に含めることもできます。
しかし、より良い方法は、Inertia が内部で使用している HTTP ライブラリである axios に組み込まれている CSRF 機能を利用することです。
Axios は XSRF-TOKEN クッキーの存在を自動的に確認します。これが存在する場合、Axios はリクエスト時に X-XSRF-TOKEN ヘッダーにトークンを含めます。
これを実装する最も簡単な方法は、サーバーサイドのミドルウェアを使用することです。各レスポンスに XSRF-TOKEN クッキーを含め、Axios から送信されるリクエスト内の X-XSRF-TOKEN ヘッダーを使用してトークンを検証するだけです。
不一致の処理
CSRF トークンの不一致が発生すると、サーバーサイドのフレームワークは通常、エラーレスポンスを返す例外をスローします。たとえば Laravel を使用している場合、TokenMismatchException がスローされ、419 エラーページが表示されます。これは有効な Inertia レスポンスではないため、エラーはモーダルで表示されます。
明らかに、これは良いユーザー体験とは言えません。より良い対処法は、ページの有効期限が切れたことを示すフラッシュメッセージとともに、直前のページへリダイレクトを返すことです。これにより、有効な Inertia レスポンスが返され、フラッシュメッセージが props として利用可能になり、ユーザーに表示できます。もちろん、これを機能させるには、Inertia と フラッシュメッセージ を共有する必要があります。
Laravel を使用している場合、アプリケーションの例外ハンドラを変更して、ユーザーを直前に表示していたページへ自動的にリダイレクトし、同時にセッションへメッセージをフラッシュすることができます。これを実現するには、アプリケーションの bootstrap/app.php ファイル内で respond 例外メソッドを使用します。
use Symfony\Component\HttpFoundation\Response;
->withExceptions(function (Exceptions $exceptions) {
$exceptions->respond(function (Response $response) {
if ($response->getStatusCode() === 419) {
return back()->with([
'message' => 'ページの有効期限が切れました。もう一度お試しください。',
]);
}
return $response;
});
});最終的に、これはユーザーにとってはるかに良い体験となります。エラーモーダルが表示される代わりに、ページの有効期限が「切れた」ことを示すメッセージが表示され、再試行するよう促されます。