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

时间:2022-10-06 13:45:16

I am trying to pass some data into my Controller, but I'm getting a 500 error. After some research, I discovered that it's caused by the CSRF token not being sent.

我试着把一些数据传递给我的控制器,但是我得到了500个错误。经过一些研究,我发现它是由CSRF令牌没有被发送引起的。

It seems like I need to include this along with the data: <?php echo $this->security->get_csrf_token_name(); ?>:"<?php echo $this->security->get_csrf_hash(); ?>"

似乎我需要将它与data: 安全- > get_csrf_token_name();》:“< ?php echo $ this - >安全- > get_csrf_hash();? > "

My JS is pretty weak, so I'm a little confused on how to alter this to include the above.

我的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 个解决方案

#1


3  

The token needs to be passed in the data argument of $.ajax.

该令牌需要在$.ajax的数据参数中传递。

This should work but see my notes below.

这应该可以,但是请看下面我的笔记。

order['<?php echo $this->security->get_csrf_token_name(); ?>'] = '<?php echo $this->security->get_csrf_hash(); ?>';

秩序[' < ?php echo $ this - >安全- > get_csrf_token_name();> ']= ' < ?php echo $ this - >安全- > get_csrf_hash();> ';

However, there are a few bad practices going on here. Mainly you should not use PHP in your javascript because this prevents you from being able to access the javascript as a separate file (this is good because browsers will cache it to make your page load faster and consume less bandwidth).

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

It's better to store the token in your order <form> html like this..

最好将令牌存储在order

html中,如下所示。

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

< input type = "隐藏" name = " < ?php echo $ this - >安全- > get_csrf_token_name();>“价值= " < ?php echo $ this - >安全- > get_csrf_hash();? > " / >

Then it will get serialized with the rest of your form data.

然后它将与您的其余表单数据序列化。

You can also store the URL in the form's action attribute. This will help your script gracefully degrade and also keeps the URL in one place instead of 2.

您还可以将URL存储在表单的action属性中。这将帮助您的脚本优雅地降级,并保持URL在一个地方而不是2。

<form id="order" method="post" action="<?=base_url()?>admin/category/update_order">

In the $.ajax call, use something like this url: $('#order').attr('action'), assuming #order is the actual form id.

在美元。ajax调用,使用如下url: $('#order').attr('action'),假定#order是实际的表单id。

#2


2  

CI stores csrf in cookie and you can fetch it from there:

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

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

The downside of this method is that jQuery doesn't natively provide cookie access. So you will need a jquery plugin.

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

#3


1  

You're correct, just add the CSRF token to your post data. You can use jQuery's $.extend function to merge your order object you already created with the CSRF token data, like this:

您是对的,只需将CSRF令牌添加到post数据中。您可以使用jQuery的$。扩展函数以合并您已经创建的订单对象和CSRF令牌数据,如下所示:

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

#4


1  

Here's a different approach. Simple function in Auth.php that returns the csrf token name and hash in JSON format. Then, in our javascript, make two ajax calls, the first to grab the csrf creds and insert them into hidden form fields, the second to handle our actual form submit.

这是一个不同的方法。简单身份验证功能。以JSON格式返回csrf令牌名称和散列。然后,在我们的javascript中,进行两个ajax调用,第一个调用获取csrf creds并将它们插入隐藏的表单字段中,第二个调用处理实际的表单提交。

// place function in Auth.php controller

//在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()

/ / 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

/ / 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>

#5


0  

I extend form_helper as MY_form_helper.php to serve csrf tokens to my own form generation code - you could use something similar:

我将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().'>';
    }

#6


0  

another solution is to use .serialize():

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

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

that will find the hidden field that stores the CSRF data.

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

#1


3  

The token needs to be passed in the data argument of $.ajax.

该令牌需要在$.ajax的数据参数中传递。

This should work but see my notes below.

这应该可以,但是请看下面我的笔记。

order['<?php echo $this->security->get_csrf_token_name(); ?>'] = '<?php echo $this->security->get_csrf_hash(); ?>';

秩序[' < ?php echo $ this - >安全- > get_csrf_token_name();> ']= ' < ?php echo $ this - >安全- > get_csrf_hash();> ';

However, there are a few bad practices going on here. Mainly you should not use PHP in your javascript because this prevents you from being able to access the javascript as a separate file (this is good because browsers will cache it to make your page load faster and consume less bandwidth).

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

It's better to store the token in your order <form> html like this..

最好将令牌存储在order

html中,如下所示。

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

< input type = "隐藏" name = " < ?php echo $ this - >安全- > get_csrf_token_name();>“价值= " < ?php echo $ this - >安全- > get_csrf_hash();? > " / >

Then it will get serialized with the rest of your form data.

然后它将与您的其余表单数据序列化。

You can also store the URL in the form's action attribute. This will help your script gracefully degrade and also keeps the URL in one place instead of 2.

您还可以将URL存储在表单的action属性中。这将帮助您的脚本优雅地降级,并保持URL在一个地方而不是2。

<form id="order" method="post" action="<?=base_url()?>admin/category/update_order">

In the $.ajax call, use something like this url: $('#order').attr('action'), assuming #order is the actual form id.

在美元。ajax调用,使用如下url: $('#order').attr('action'),假定#order是实际的表单id。

#2


2  

CI stores csrf in cookie and you can fetch it from there:

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

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

The downside of this method is that jQuery doesn't natively provide cookie access. So you will need a jquery plugin.

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

#3


1  

You're correct, just add the CSRF token to your post data. You can use jQuery's $.extend function to merge your order object you already created with the CSRF token data, like this:

您是对的,只需将CSRF令牌添加到post数据中。您可以使用jQuery的$。扩展函数以合并您已经创建的订单对象和CSRF令牌数据,如下所示:

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

#4


1  

Here's a different approach. Simple function in Auth.php that returns the csrf token name and hash in JSON format. Then, in our javascript, make two ajax calls, the first to grab the csrf creds and insert them into hidden form fields, the second to handle our actual form submit.

这是一个不同的方法。简单身份验证功能。以JSON格式返回csrf令牌名称和散列。然后,在我们的javascript中,进行两个ajax调用,第一个调用获取csrf creds并将它们插入隐藏的表单字段中,第二个调用处理实际的表单提交。

// place function in Auth.php controller

//在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()

/ / 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

/ / 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>

#5


0  

I extend form_helper as MY_form_helper.php to serve csrf tokens to my own form generation code - you could use something similar:

我将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().'>';
    }

#6


0  

another solution is to use .serialize():

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

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

that will find the hidden field that stores the CSRF data.

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