避免在第二次POST请求时,codeigniter出现403错误。

问题描述 投票:1回答:2

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

任何请求都能正常工作,但如果我需要执行另一个请求(不介意是否相同)... ... 我不能!我需要刷新页面才能执行。我需要刷新页面来执行一个新的请求,否则,我会得到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');
       }
   });
}
php codeigniter error-handling http-status-code-403
2个回答
1
投票

你遇到了一个过期的CSRF令牌。有多种方法可以解决这个问题(每一种方法都有不同的复杂性和安全级别)。

1.-完全禁用CSRF(不推荐,除非你所有的表单都在一个安全的区域内,每个人都是登录的,而且没有办法获得跨域请求,这种可能性不大。

2.-为CSRF功能定义异常。在 application/config/config.php 你会发现一个叫做 $config['csrf_exclude_uris'] 在这里您可以添加所有您希望不强制执行CSRF检查的controllermethod对。

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

4.-在第一次提交后手动获取一个再生的令牌,并在第二次提交时一并传递。这是最安全的方式来解决你的问题,但也是最复杂的。您可以在 Codeigniter的安全类文档在这里


1
投票

为了手动重新生成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令牌再生的概念。

© www.soinside.com 2019 - 2024. All rights reserved.