简体   繁体   English

Codeigniter CSRF Ajax错误

[英]Codeigniter csrf ajax error

I am making an ajax call for a like/dislike on a video and I found out that I need to pass the CSRF token when I submit the data. 我正在对视频进行“喜欢/不喜欢”的ajax调用,我发现提交数据时需要传递CSRF令牌。

I have to calls one to when the user clicks like and one when the user clicks dislike. 当用户单击喜欢时,我必须调用一个;当用户单击不喜欢时,我必须调用一个。 My issue is if the user clicks like and realizes they made a mistake and click on dislike they will receive an error: 我的问题是,如果用户单击喜欢并意识到他们犯了一个错误,然后单击不喜欢,则他们将收到错误:

403 Forbidden

The action you have requested is not allowed.

If the user refreshes the page first and changes their selection everything is ok. 如果用户首先刷新页面并更改其选择,则一切正常。 it's only when they try to switch from one to the other without refresh. 只有当他们尝试从一个切换到另一个而没有刷新时。

Here is my code: 这是我的代码:

<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>

Why does it give the user an error when they make changes to their selection? 更改选择时,为什么会给用户带来错误?

So I copied this paragraph from the user guide. 因此,我从用户指南中复制了此段。

"Tokens may be either regenerated on every submission (default) or kept the same throughout the life of the CSRF cookie. The default regeneration of tokens provides stricter security, but may result in usability concerns as other tokens become invalid (back/forward navigation, multiple tabs/windows, asynchronous actions, etc). You may alter this behavior by editing the following config parameter. " “令牌可以在每次提交时重新生成(默认),也可以在CSRF Coo​​kie的整个生命周期内保持不变。令牌的默认重新生成可提供更严格的安全性,但由于其他令牌无效(向后/向前导航,多个标签页/窗口,异步操作等)。您可以通过编辑以下config参数来更改此行为。

Try to add/edit this line in your config file: 尝试在配置文件中添加/编辑此行:

$config['csrf_regeneration'] = TRUE; $ config ['csrf_regeneration'] = TRUE;

There's another way to do this that doesn't require disabling csrf regeneration. 还有另一种方法,不需要禁用csrf再生。 you can send the new csrf token back to the calling ajax script. 您可以将新的csrf令牌发送回调用ajax脚本。

In your CodeIgniter Controller: 在您的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 = the data to return to the browser $ data =返回浏览器的数据

$csrf = new csrf token to be used by the browser for next ajax post request $ csrf =新的csrf令牌,供浏览器用于下一个ajax发布请求

Obviously you can output this in other ways but JSON is used mostly with ajax calls. 显然,您可以通过其他方式输出此内容,但是JSON主要用于ajax调用。 Also include this token in every post response to be used for the next post request 在每个帖子响应中也要包含此令牌,以用于下一个帖子请求

Then in your next ajax request (javascript): 然后在您的下一个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 );
    }
});

Also remember that where I've got csrf_token:token replace crf_token with the name of your token found in application/config/config.php on line that states $config['csrf_token_name'] = 'csrf_token'; 还要记住,在我有csrf_token:tokencrf_token替换为在application / config / config.php中找到的令牌名称,该行指出$config['csrf_token_name'] = 'csrf_token';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM