Blade(サーバーサイド)の中に React コンポーネント(クライアントサイド)を組み込むという前提で進めます。
この構成で fetch を使って POST リクエストを送る場合、「Blade 側(サーバー)が生成した CSRF トークンを、JavaScript(React)側へ渡して fetch のヘッダーにセットする」です。
🔄 全体の処理の流れ(概要図)
-
【Blade】 ページ表示時に、CSRF トークンを
metaタグに埋め込んでおく。 -
【React】 画面が読み込まれたら、JavaScript で
metaタグからトークンを読み取る。 -
【React】
fetchで POST 送信する際、リクエストヘッダー(X-CSRF-TOKEN)にそのトークンを乗せる。 - 【サーバー】 届いたヘッダーのトークンを検証し、問題なければ処理を実行する。
💻 具体的なコードと実装ステップ
ステップ 1. 【Blade 側】meta タグにトークンを仕込む
まず、React コンポーネントを読み込んでいるベースの Blade ファイル(index.blade.php など)の <head> タグ内に、CSRF トークンを出力する meta タグを記述します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>マイアプリ</title>
</head>
<body>
<div id="app"></div>
@vite(['resources/js/app.jsx'])
</body>
</html>
ステップ 2. 【React 側】fetch のヘッダーにトークンをセットして POST する
次に、React コンポーネント側で fetch を使ってリクエストを送る処理です。JavaScript で先ほどの meta タグから値を取得し、ヘッダーに X-CSRF-TOKEN という名前でセットします。
import React, { useState } from 'react';
export const SendMoneyForm = () => {
const [amount, setAmount] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
// 1. HTMLの <meta name="csrf-token"> からトークンの値を取得する
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
try {
// 2. fetch で POST リクエストを送信
const response = await fetch('/api/send-money', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// サーバーが検証できるようにヘッダーにトークンを入れる
'X-CSRF-TOKEN': csrfToken,
},
body: JSON.stringify({ amount: amount }),
});
if (response.ok) {
alert('送金が完了しました!');
} else {
alert('エラーが発生しました(トークンエラーの可能性あり)');
}
} catch (error) {
console.error('通信失敗:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="金額を入力"
/>
<button type="submit">送金する</button>
</form>
);
};
ステップ 3. 【サーバー側】自動検証
リクエストがサーバー(バックエンド)に届くと、Webフレームワークが持つ「CSRF検証ミドルウェア」が自動的に働きます。
- サーバーは、届いたリクエストのヘッダーにある
X-CSRF-TOKENをチェックします。 - サーバーがセッションに保持しているトークンと一致すれば、コントローラーの処理(データの保存など)へ進めます。
- トークンが古い、あるいは存在しない場合は、一歩も中に入れずに
419 Unknown Status(または403 Forbidden) などのエラーを返してリクエストを遮断します。