【问题标题】:Csrf token is valid just in first submit using ajaxCsrf 令牌仅在使用 ajax 首次提交时有效
【发布时间】:2015-08-06 15:18:27
【问题描述】:

我想使用 jquery ajax 提交我的表单,没关系,但只是我第一次点击提交,这是我的代码。

    <!-- input code from the form -->
    <input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash(); ?>" />

    <!-- js code -->
    $.ajax({
        url: ajaxurls.ask,
        type: 'POST',
        data: formData,
        contentType: false,       // The content type used when sending data to the server.
        cache: false,             // To unable request pages to be cached
        processData:false, 
        success: function (html) {
            var data = jQuery.parseJSON(html);
            if(data.status == 'ok') {
                $('.row_question_form').after(data.response.html);
                $('.question_' + data.response.question[0].question_id).hide().fadeIn();
                $('#question_form').val('');
                $('#thumbnails').empty();
                $('#ask_question_messages').empty();
                $('#ask_question_messages').html(data.message);
            }else if(data.status == 'error'){
                $('#ask_question_messages').empty();
                $('#ask_question_messages').html(data.message);
            }
        }
  });

您可能会说设置$config['csrf_regenerate'] = FALSE;,但在这种情况下,有人可以使用这样的应用程序在我的数据库中创建数百条记录:

http://i.imgur.com/qA4pqyr.png

【问题讨论】:

  • 第一次可以提交表单吗?
  • 是的,当第一次调用控制器时,csrf 会发生变化,因此第二次无法正常工作。我必须刷新页面才能再次工作。
  • CSRF 令牌是一次性使用的。
  • 是的,但是如何将 CSRF 与 ajax 一起使用?我可以多次使用相同的表单而无需重新加载页面(但是当我发出 ajax 请求时,csrf 令牌会更改,下次表单将不再起作用)

标签: php jquery codeigniter


【解决方案1】:

每个 CSRF Token 只能提交一个 POST 是正确的,因为它们是一次性使用的。

如果您的意图是更改服务器端数据,POST 是正确的方法。

但如果你只是想从服务器读取数据,你应该使用 GET 方法。

这是nicely explained here


如果您想禁用 CSRF 续订because it would not be necessary to generate a new token per request,您可以在 CI v3.0 中通过设置配置来实现:

$config['csrf_regenerate'] = FALSE;

另一方面,如果您更喜欢获取新令牌并刷新表单以进行新提交,read this howto

【讨论】:

  • 我需要将数据插入数据库,所以 POST 是正确的方法。正如你在这里看到的:link 我有那个表格可以提问。但我需要能够在不重新加载页面的情况下提出 2 个或更多问题。我使用 ajax,所以立即显示答案。一个解决方案是在 ajax 成功时更新页面 csrf。示例:$.ajax({ url: ajaxurls.ask, type: 'POST', data: formData,success: function (html) { var data = jQuery.parseJSON(html); $('input[name="csrf_ask_name"]').val(data.new_csrf); } 但这仍然安全吗?
  • 您应该在每个 FORM/POST 中只提交一次,因此您必须在每次提交后加载一个新表单(因此,一个新令牌)。您可以使用 AJAX GET 请求新表单,其中将包含一个新令牌。只需添加一个控制器方法来提供您需要加载的表单,然后用请求的 AJAX 替换旧的。为每个人请求“免费令牌”时要小心安全问题,因为您将禁用它应该提供的安全功能。也许其他人可以解释这方面的安全问题。
  • 我认为如果我请求一个新的表单或一个带有令牌的新输入是等效的。
  • 我认为是。但是有很多应用程序从 AJAX 加载表单,所以我相信实际上有一种方法可以安全地获得 新表单而没有风险。
  • @IonVasile 请阅读新资源以检查其中任何一个(完全不同的方法)是否符合您的需求。似乎有关 CSRF 令牌的安全问题讨论更进一步,是否续订取决于您。
猜你喜欢
  • 1970-01-01
  • 2012-04-10
  • 2018-02-22
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 2011-05-08
  • 2017-01-08
  • 1970-01-01
相关资源
最近更新 更多