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