基本私の記事は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の通信の仕方は追々記事にする予定です。
コメント