1. ホーム > 
  2.  CodeIgniter
セキュリティ

CodeIgniter3でCSRF対策機能をONにしたらAjaxでPOSTできなかった件

2018/10/20 - CodeIgniter, Javascript, PHPWebアプリ

CodeIgniter3でCSRF(クロスサイトリクエストフォージェリ)対策機能を使用した時に、AjaxでPOSTできなくて、結構ハマったのでメモ。

CodeIgniter3では、config.phpの$config[‘csrf_protection’]を

$config['csrf_protection'] = FALSE;
$config['csrf_regenerate'] = TRUE;

を下のコードのようにTRUEに

$config['csrf_protection'] = TRUE;
$config['csrf_regenerate'] = FALSE;

に変更すると、CSRF対策機能がオンになります。
これで、普通にPOSTしてもエラーになるようになります。
$config[‘csrf_regenerate’]は、FALSEにしないと1度しか動きません。
その都度、トークンを作り直す設定です。オンにしても必ずしもセキュリティが上がるというわけではないようなので、サクッとオフにします。

 

フォームヘルパーを使用しない場合、CSRFトークンを作ってやる必要があります。

コントローラーに、下記のように、送るデータ以外に、

//crsfトークン作成
$data['csrf'] = array(
            'name' => $this->security->get_csrf_token_name(),
            'hash' => $this->security->get_csrf_hash()
);
//ビューに送る(sampleView.php)
$this->load->view("sampleView",$data);

トークンを生成しセット。
ビューに下記のコードを記述。

//csrfトークン埋め込み
<input id="token" type="hidden" name="<?= $csrf['name'];?>" value="<?= $csrf['hash'];?>">

//送りたいデータ(なんでもいいです、たまたまhiddunにしてます)
<input id="hform4" type="hidden" name="hform4" value="CSRF Ajax ">

Javascriptファイルに

$(function(){
//ajaxTestというidのボタンをクリックイベント
  $("#ajaxTest").on('click',function(){

  var csrf_name = $("#token").attr('name'); // viewに生成されたトークンのname取得
  var csrf_hash = $("#token").val(); // viewに生成されたトークンのハッシュ取得
  var mess = $("#hform4").val(); // viewに生成された送信データ取得

  var postdata = {};
  postdata[csrf_name] = csrf_hash;
  postdata["request"] = mess; // これと同じ感じ→ data:{"csrf_test_name":csrf_hash,"request": mess},

  $.ajax({
      type:"POST",
      url: url + "sample/test",//送り先
      data: postdata
      }).done(function(data) {
           // 成功時の処理
           alert(data);

      }).fail(function(data) {
          // エラー時の処理
          alert('通信ができない状態です。');

      });
   });
});

受け側のコントローラーファイルに

public function test(){
//crsfトークン判定
if ( $this->input->method(TRUE) !== 'POST' )
        {
            show_404();
        }
//本命のデータ受け取り
$res = $this->input->post('request');
        $res = $res."成功";
        echo $res;
}

これでOK。【CSRF Ajax 成功】とアラートが出れば成功です。

最初、普通にトークンをデータにセットすればいいのがわからず苦労しました(笑)
ちなみに、サニタイズ等は省略しています。
その辺の機能もCodeIgniter3にはあるので、使うか自前で実装するかは、お好みで。

 

コメント

コメントを書く

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA