LaravelでReactのコンポーネントを用いてフォーム送信を行いたい場合に、LaravelのCSRFトークンを含める方法について調べてみました。
何をしたいのか?
通常、Laravelでフォーム送信する際、CSRFトークンをリクエストに含める必要がある。
Laravel独自のテンプレートエンジンのBladeでは、@csrfディレクティブを利用することでCSRFトークンを生成することができる。
しかし、このフォーム送信をLaravel側ではなく、React側のコンポーネントの中で行いたい場合、どうすれば良いのだろうかと疑問に感じた。
そこで、今回はReact側でフォーム送信する場合に、CSRFトークンを含める方法について調べてみたので説明します。
1. Laravelでcsrfトークンを生成する
@csrfディレクティブも含めて、CSRFトークンはLaravel側の機能なので、トークンの生成はLaravel側で行う必要があります。
csrfトークンの生成はLaravelの「csrf_token()」関数を用いて生成します。
2. HTMLのmetaタグにcsrfトークンを埋め込む
生成したトークンはReact側に渡す必要があります。
トークンを渡す方法は色々ありますが、今回はHTMLのmetaタグ内に埋め込む方法を用います。
<meta name="csrf-token" content="{{ csrf_token() }}">
3. React側でCSRFトークンを取得する
次に、2.でセットしたmetaタグのcsrfトークンをReactのコンポーネントで取得します。
以下は、TSXで記述した例です。
トークンの取得方法は様々ありますが、以下のサンプルではuseRefフックを用いています。
const Form = () => {
const metaCsrfToken = document.querySelector("meta[name='csrf-token']") as HTMLMetaElement;
const csrfToken = useRef<string>(metaCsrfToken.content);
...
}
4. Formタグにcsrfトークンを含める
最後に、取得したcsrfトークンをformタグの中に含めます。
inputタグのtype属性を「hidden」、name属性の値を「_token」、value属性の値を「トークン」に設定することでcsrfトークンを含めることができます。
以上で、LaravelでReact側のForm送信が可能になります。
const Form = () => {
const metaCsrfToken = document.querySelector("meta[name='csrf-token']") as HTMLMetaElement;
const csrfToken = useRef<string>(metaCsrfToken.content);
return(
<form action="/hoge" method="post">
<input type="hidden" name="_token" value={ csrfToken.current } />
....
<button type="submit">登録</button>
</form>
);
}
まとめ
LaravelでReact側のForm送信を実装したい場合は、以下の手順で行います。
- Laravel側でCSRFトークンを生成する
- HTMLのmetaタグにcsrfトークンを埋め込む
- React側でCSRFトークンを取得
- Form送信時にトークンを含める
参考サイト
- LaravelのフォームをReactで使う際にcsrfトークンを含める方法
- Laravel】CSRF対策 「@csrf」や「 {{ csrf_field() }} 」が意味するもの