在第二个 POST 请求中避免 codeigniter 中的错误 403

Avoid error 403 in codeigniter on a second POST request

我不明白为什么我不能在不刷新页面的情况下执行多个请求。

任何请求都可以正常工作,但是如果我需要执行另一个请求(不管是否相同)...我不能!我需要刷新页面来做一个新的请求,否则,我会得到错误 403。

所有代码都在工作,只是,任何请求都以刷新页面结束。我不喜欢那样,因为我认为它不专业。

我需要在 codeigniter 中更改什么才能在不刷新页面的情况下允许多个请求?

评论更新:我使用 csrf 保护,我不想禁用它。

@Vickel 这是其中一个请求(所有请求都几乎相同,只是 url 和数据)...没有表格。

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');
       }
   });
}

您遇到了过期的 CSRF 令牌。有多种解决方法(每种方法都有不同的复杂性和安全级别)

1.- 完全禁用 CSRF(不推荐,除非您的所有表单都位于每个人都登录的安全区域内,并且无法获得跨域请求,这是不太可能的。

2.- 定义 CSRF 功能的例外情况。在 application/config/config.php 中,您会找到一个名为 $config['csrf_exclude_uris'] 的数组,您可以在其中添加您希望不对其执行 CSRF 检查的所有 controller/method 对

3.- 禁用 CSRF 再生。在 application/config/config.php 中,您可以将 $config['csrf_regenerate'] 设置为 false。这将防止在每次请求后重新生成 CSRF 令牌,这将允许您进行多次提交而不会被 CSRF 检查阻止

4.- 第一次提交后手动获取重新生成的令牌,并与第二次提交一起传递。这是解决问题的最安全方法,但也是最复杂的方法。您可以在 Codeigniter's Security Class documentation here

中深入了解这一点

为了手动重新生成 CSRF 令牌,您可以执行以下操作:

  1. 在您的视图中创建一个隐藏的输入字段,用于存储您的 csrf 令牌
  2. 在您的控制器中,您创建一个新令牌并将其与您的 ajax 响应一起发回
  3. 在您的 ajax 成功功能中,您更新隐藏的输入字段

现在您可以发送新请求了

查看:

<?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
      }
})

控制器:

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

您可能需要稍微调整一下,但它展示了手动 csrf 令牌重新生成的概念