【问题标题】:Avoid error 403 in codeigniter on a second POST request在第二个 POST 请求中避免 codeigniter 中出现错误 403
【发布时间】:2020-06-08 12:48:22
【问题描述】:

我不明白为什么不刷新页面就不能执行多个请求。

任何请求都可以正常工作,但是如果我需要执行另一个请求(不管它是否相同)......我不能!我需要刷新页面才能执行新请求,否则会出现错误 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');
       }
   });
}

【问题讨论】:

  • 我们无法回答这个问题。我们不知道您所说的“执行请求”是什么意思,非常模糊。
  • 执行、制作或您用来解释您正在发出发布/获取请求的任何其他动词
  • 好的,那是哪个? post/get/head/put/delete/connect/options/trace?我们还需要查看请求是如何发出的,您的整个项目结构是如何设置的,以确定您收到 403 错误的原因,这表明您的服务器告诉客户端他们无权执行某项操作。
  • @CarlosDiaz 您至少应该分享您所面临问题的屏幕截图。
  • 这听起来像 csrf protection=true 并且没有隐藏的 csrf 字段。你能确认一下吗?

标签: php codeigniter error-handling http-status-code-403


【解决方案1】:

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

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

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

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

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

中深入了解这一点

【讨论】:

    【解决方案2】:

    要手动重新生成 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 令牌再生如何工作的概念

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2013-10-20
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 2021-06-07
      相关资源
      最近更新 更多