Avoid error 403 in codeigniter on a second POST request

强颜欢笑 提交于 2020-06-28 08:13:51

问题


I can't understand why I cannot do more than one request without refreshing page.

Any request is working fine, but If I need to execute another request (don't mind if it's the same or not)... I can't! I need to refresh the page to do a new request, otherwise, I'll get error 403.

All the code is working, just, any request is finishing with refreshing the page. I don't like that because I consider it's not professional.

What do I need to change in codeigniter to allow more than one request without refreshing the page?

update from comment: I use csrf protection and I don't want to disable it.

@Vickel this is one of the requests (all of them is almost the same, just url and data)... there's no form.

function set_tracking(order_id)
{
    $.ajax({
        type: "POST",
        data: {
            order_id: order_id
       },
       url: trackingURL,
       beforeSend: function() {
          $('.lds-default').removeClass('hidden');
       },
       success: function (response) {
           console.log(response);
           if(response.error)
           {
                show_form_errors(lang['productions_error_not_set_tracking']);
           } else {
               $('#set_tracking .modal-title').html(lang['productions_set_tracking_title']);
               $('#set_tracking').modal('show');

               $('#set_tracking #order_id').val(order_id);
           }
       },
       error: function (event) {
           if (event.status !== 401) {
               show_form_errors(lang['companies_error_deleting_segment']);
           }
       },
       complete: function() {
           $('#confirm_message').modal('hide');
           $('.lds-default').addClass('hidden');
       }
   });
}

回答1:


You're encountering an expired CSRF token. There's multiple ways around this (each with different complexity and security levels)

1.- Disable CSRF altogether (not recommended unless all your forms live within a secure area where everyone is logged in and there's no way to get a cross-domain request, which is unlikely.

2.- Define exceptions for the CSRF functionality. In application/config/config.php you'll find an array called $config['csrf_exclude_uris'] where you can add all the controller/method pairs for which you wish the CSRF checks to not be enforced

3.- Disable CSRF regeneration. In application/config/config.php you could set $config['csrf_regenerate'] to false. This will prevent the CSRF token to be regenerated after each request, which would allow you to make more than one submission without being blocked by the CSRF check

4.- Manually get a regenerated token after the first submission and pass it along with the second submission. This is the most secure way to address your issue, but the most complex. You can read about this in depth in the Codeigniter's Security Class documentation here




回答2:


in order to manually regenerate the CSRF token you can do the following:

  1. create an hidden input field in your view, which stores your csrf token
  2. in your controler, you create a new token and send it back with your ajax response
  3. in your ajax success function, you update your hidden input field

now you are ready for sending a new request

view:

<?php
  $csrf = array(
        'name' => $this->security->get_csrf_token_name(),
        'hash' => $this->security->get_csrf_hash()
);
?>
<input type="hidden" name="<?=$csrf['name'];?>" value="<?=$csrf['hash'];?>" />

javascript:

tn='<?php echo $this->security->get_csrf_token_name(); ?>';
th=$('input[name="'+tn+'"]').val();
csfrData={tn:th};

$.ajax({
      type: "POST",
      dataType:json,
      data: {
            order_id: order_id,
            csrf:csfrData  // send current token
      }, 
      //etc...
      success: function (response) {
          // update hidden input field with new token
          $('input[name="'+response.csrf.csrf_name+'"]').val(response.csrf.csrf_hash)
          // etc
      }
})

controller:

function your_tracking_url(){
   $data['yourdata']=array() // whatever you return
   $data['csrf']=$this->get_csrf();
   echo json_encode($data);
}
function get_csrf(){
    // creating a new token
    $csrf=array('csrf_name'=>$this->security->get_csrf_token_name(),'csrf_hash'=>$this->security->get_csrf_hash());
    return $csrf;
}

you might need to adapt this a little bit, but it shows the concept how manual csrf token regeneration works



来源:https://stackoverflow.com/questions/62262470/avoid-error-403-in-codeigniter-on-a-second-post-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!