基本私の記事はIBMi/AS400をベースにやっています。ご了承のほど。
LaravalではPOST通信時にCSRFトークンを送らないといけないのはすでに知っている。
なのでFormを設置時に下記のように{{ csrf_field }}を入れないといけない。
これを入れる理由はセキュリティのため。クロスサイトリクエストフォージェリ対策。詳しくはググってほしい。
<form action="{{ url('hogehoge/post')}}" method="POST">
{{ csrf_field() }}
<input type="text" name="hoge">
<input type="submit">
</form>
この{{ csrf_field }}は、実際には下記のようなものが吐き出される。これがないとPOST時にLaravel大先生から怒られてしまう。
<input type="hidden" name="_token" value="JOLyzlbt********anpDvE6PkyxnUaLw">
今回Ajax通信をしようとしてみた。
詳細は割愛するとして、こんな感じでPOSTで通信するわけだが、CSRF対策を何もせずにやると当然のごとくエラーになる。
// Ajax通信
let xhr = new XMLHttpRequest();
// パス
xhr.open('post','{{url('testajaxjq/')}}',true);
そのときブラウザのコンソールに出るエラーコードは419。
これはいわずとしれたCSRF対策、前述のものが出来ていないと怒られている。
しからばどう書けばいいのか。
書き方は、request.setRequestHeaderにそれを書いてあげる。
xhr.setRequestHeader('X-CSRF-TOKEN','{{ csrf_token() }}');
こう書く。{{ csrf_field }}にすれば<input>から</input>まで要素から全てが生成されるが、{{ csrf_token() }}にすればさっきの
JOLyzlbt********anpDvE6PkyxnUaLw
の部分だけが吐き出されるわけですね。
なので、結果的に、
xhr.setRequestHeader('X-CSRF-TOKEN','JOLyzlbt********anpDvE6PkyxnUaLw');
といった形で収まり、うまくいく。
jQueryの書き方はこんな感じ
$.ajax({
headers: {
'X-CSRF-TOKEN' : '{{csrf_token()}}',
},
type: "POST",
以下略..
別解
JavaScriptは別ファイルにすると思いますが、そうなってくるとJavaScriptコードの中で{{ csrf_token() }}が使えないので、
Bladeのヘッダー部に
<meta id="csrf-token" content="{{ csrf_token() }}">
とメタデータで入力しておき、
こうやって取得するしかないのかも。
let csrf = document.getElementById('csrf-token').content;
xhr.setRequestHeader('X-CSRF-TOKEN','csrf');
下記はその場合のjQueryの書き方。
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[id="csrf-token"]').attr('content')
},
type: "POST",
以下略...
Ajax通信の決まり事も割愛させていただきますが、Laravel/IBMi/Ajaxの通信の仕方は追々記事にする予定です。


コメント