简体   繁体   中英

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.

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

Try to add/edit this line in your config file:

$config['csrf_regeneration'] = TRUE;

There's another way to do this that doesn't require disabling csrf regeneration. you can send the new csrf token back to the calling ajax script.

In your CodeIgniter Controller:

$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

$csrf = new csrf token to be used by the browser for next ajax post request

Obviously you can output this in other ways but JSON is used mostly with ajax calls. Also include this token in every post response to be used for the next post request

Then in your next ajax request (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';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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