Codeigniter csrf ajax错误

时间:2015-08-03 19:22:09

标签: javascript php jquery ajax codeigniter

我正在对视频做出类似/不喜欢的ajax调用,我发现在提交数据时我需要传递CSRF令牌。

当用户点击时,我必须调用一个,当用户点击不喜欢时,我必须调用一个。我的问题是,如果用户点击了,并意识到他们犯了错误并点击不喜欢他们会收到错误:

403 Forbidden

The action you have requested is not allowed.

如果用户首先刷新页面并更改其选择,则一切正常。只有当他们试图在没有刷新的情况下从一个切换到另一个时才会这样做。

这是我的代码:

<script>
  // like btn
  $('.like-btn').click(function() {
    $('.dislike-btn').removeClass('text-danger');    
    $(this).addClass('liked-video');
    $.ajax({
      type:"POST",
      url: '<?=base_url("videos/like_video")?>',
      data: {video_id: <?=$video_id?>, user_id: <?=$logged_in_userid?>, value: "like", '<?=$this->security->get_csrf_token_name()?>':'<?=$this->security->get_csrf_hash()?>'},
      success: function() {}
    });
  });

  // dislike btn
  $('.dislike-btn').click(function() {
    $('.like-btn').removeClass('text-success');
    $(this).addClass('disliked-video');
    $.ajax({
      type:"POST",
      url: '<?=base_url("videos/dislike_video")?>',
      data: {video_id: <?=$video_id?>, user_id: <?=$logged_in_userid?>, value: "dislike", '<?=$this->security->get_csrf_token_name()?>':'<?=$this->security->get_csrf_hash()?>'},
      success: function() {}
    });
  });
</script>

为什么在更改选择时会给用户一个错误?

2 个答案:

答案 0 :(得分:1)

所以我从用户指南中复制了这一段。

“标记可以在每次提交时重新生成(默认),也可以在CSRF cookie的整个生命周期内保持不变。标记的默认重新生成提供更严格的安全性,但可能导致可用性问题,因为其他标记变得无效(返回/前向导航,多个选项卡/窗口,异步操作等。)您可以通过编辑以下配置参数来改变此行为。“

尝试在配置文件中添加/编辑此行:

$ config ['csrf_regeneration'] = TRUE;

答案 1 :(得分:0)

还有另一种方法可以禁用csrf再生。您可以将新的csrf令牌发送回调用的ajax脚本。

在CodeIgniter控制器中:

$data = array('data'=> 'data to send back to browser');
$csrf =  $this->security->get_csrf_hash();
$this->output
    ->set_content_type('application/json')
    ->set_output(json_encode(array('data' => $data, 'csrf' => $csrf)));

$ data =要返回浏览器的数据

$ csrf =浏览器用于下一个ajax发布请求的新csrf令牌

显然你可以用其他方式输出它,但JSON主要用于ajax调用。还要在每个帖子响应中包含此标记,以用于下一个帖子请求

然后在你的下一个ajax请求(javascript)中:

var token = data.csrf;

$.ajax({
    url: '/next/ajax/request/url',
    type: 'POST',
    data: { new_data: 'new data to send via post', csrf_token:token },
    cache: false,
    success: function(data, textStatus, jqXHR) {
        // Get new csrf token for next ajax post
        var new_csrf_token = data.csrf     
       //Do something with data returned from post request
    },
    error: function(jqXHR, textStatus, errorThrown) {
      // Handle errors here
      console.log('ERRORS: ' + textStatus + ' - ' + errorThrown );
    }
});

另请注意,我已经csrf_token:tokencrf_token替换为您在app / config / config.php中找到的令牌名称$config['csrf_token_name'] = 'csrf_token';