如何将Codeigniter中的CSRF包含到ajax数据中

时间:2012-06-29 21:50:48

标签: codeigniter jquery

我正在尝试将一些数据传递到我的Controller中,但是我收到500错误。经过一些研究,我发现它是由CSRF令牌未发送引起的。

似乎我需要将其与数据<?php echo $this->security->get_csrf_token_name(); ?>:"<?php echo $this->security->get_csrf_hash(); ?>"

一起包含在内

我的JS非常弱,所以我对如何改变它以包含上述内容感到困惑。

<script type="text/javascript"> 
$(document).ready(function() {
    $("#order").sortable({
        update : function (event, ui) {
            order = $('#order').sortable('serialize');
            $.ajax({
                url: "<?=base_url().'admin/category/update_order'?>",
                type: "POST",
                data: order,
                success: function(response){
                    console.log(response);
                }
            });
        }
    });
}
);
</script>

6 个答案:

答案 0 :(得分:3)

令牌需要在data的{​​{1}}参数中传递。

这应该有用,但请看下面的笔记。

$.ajax

然而,这里有一些不良做法。主要是你不应该在你的javascript中使用PHP,因为这会阻止你作为一个单独的文件访问javascript(这很好,因为浏览器会缓存它以使你的页面加载更快,消耗更少的带宽)。

最好将令牌存储在您的订单order['<?php echo $this->security->get_csrf_token_name(); ?>'] = '<?php echo $this->security->get_csrf_hash(); ?>'; html中,如此...

<form>

然后它将使用其余的表单数据进行序列化。

您还可以将URL存储在表单的action属性中。这将有助于您的脚本正常降级,并将URL保留在一个位置而不是2。

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

<form id="order" method="post" action="<?=base_url()?>admin/category/update_order"> 调用中,使用类似$.ajax之类的内容,假设#order是实际的表单ID。

答案 1 :(得分:2)

CI将csrf存储在cookie中,您可以从那里获取它:

var csrf = $.cookie('csrf_cookie_name');

此方法的缺点是jQuery本身不提供cookie访问。所以你需要一个jquery plugin

答案 2 :(得分:1)

你是对的,只需将CSRF令牌添加到你的帖子数据中。您可以使用jQuery的$ .extend函数将您已创建的订单对象与CSRF令牌数据合并,如下所示:

$.extend(alerts, {
'<?php echo $this->security->get_csrf_token_name(); ?>' :
'<?php echo $this->security->get_csrf_hash(); ?>' });

答案 3 :(得分:1)

这是一种不同的方法。 Auth.php中的简单函数,它以JSON格式返回csrf标记名称和哈希。然后,在我们的javascript中,进行两次ajax调用,第一次获取csrf信用并将其插入隐藏的表单字段,第二次处理我们的实际表单提交。

//在Auth.php控制器中放置函数

public function get_csrf()
{
    $csrf['csrf_name'] = $this->security->get_csrf_token_name();
    $csrf['csrf_token'] = $this->security->get_csrf_hash();

    echo json_encode($csrf);
}

// myFunction()

<script type="text/javascript">
function myFunction() {

    // first ajax call to grab the csrf name and token
    // from our get_csrf() function in Auth.php
    $.ajax({
        type: "GET",
        dataType: 'json',
        url: "https://<your_domain>.com/auth/get_csrf", //replace with your domain
        success: function (data) {

            // assign csrf name and token to variables
            csrf_name = data.csrf_name;
            csrf_token = data.csrf_token;

            // assign field1 and field2 field values to variables
            var form_field1 = document.getElementById('field1').value;
            var form_field2 = document.getElementById('field2').value;

            // insert csrf creds into form
            $('#csrftoken').attr('name', csrf_name);
            $('#csrftoken').val(csrf_token);

            // second ajax call -- this is our form handler
            $.ajax({
                type: "POST",
                url: "https://<your_domain>.com/<your_controller>/<your_function>", //replace with your domain/controller/function
                data: {
                    // ES6 computed property keys are great...
                    [csrf_name] : csrf_token,
                    "field1" : form_field1,
                    "field2" : form_field2
                      },
                success: function(data) {

                    // handle the return from your form submit
                    if (data == "ok") {
                        console.log("Success!");
                        $("#infoMessage").html("<p>Success</p>").fadeIn(300);

                    } else {

                        console.log("Oops!");
                        $("#infoMessage").html("<p>Oops!</p>");

                    }

                }
            });

        }
    });

}
</script>

// html

<div id="infoMessage"></div>

<form method="post" accept-charset="utf-8">

    <input type="hidden" id="csrftoken" name="" value="" />

    <label for="field1">Field 1:</label> <br />
    <input type="text" name="field1" id="field1"  />

    <label for="field2">Field 2:</label> <br />
    <input type="text" name="field2" id="field2"  />

    <input type="button" name="submit" value="SUBMIT" onclick="myFunction()" />

</form>

答案 4 :(得分:0)

我将form_helper扩展为MY_form_helper.php以将csrf令牌提供给我自己的表单生成代码 - 您可以使用类似的内容:

    function secure_form() {
        $CI =& get_instance();
        return '<input type="hidden" name='.$CI->security->get_csrf_token_name().' value='.$CI->security->get_csrf_hash().'>';
    }

答案 5 :(得分:0)

另一个解决方案是使用.serialize():

$.post("user/save", $('#frmUser').serialize(),function(html){
        $("#results").html(html);
});

将找到存储CSRF数据的隐藏字段。