javascript - 刷新 AjaxPOST 数据表上的 CSRF token : CodeIgniter

标签 javascript php jquery codeigniter datatable

我正在尝试让数据表在我的网站上运行。但是当我单击搜索、下一页、排序时,它不起作用。这是因为未重新生成 CSRF token 。

这是我的代码:

HTML

<input type="hidden" id="hash" name="csrf_test_name" value="802daa2efaf69edb83b571d7bf7510aa">
        <table id="test-table" class="table table-hover">
            <thead>
                <tr>
                    <th>No</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Phone</th>
                    <th>Address</th>
                    <th>City</th>
                    <th>Country</th>
                </tr>
            </thead>
            <tbody>
            </tbody>

            <tfoot>
                <tr>
                    <th>No</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Phone</th>
                    <th>Address</th>
                    <th>City</th>
                    <th>Country</th>
                </tr>
            </tfoot>
        </table>

JS

<script type="text/javascript">

var table;

$(document).ready(function() {

//datatables
table = $('#test-table').DataTable({ 

    "processing": true, //Feature control the processing indicator.
    "serverSide": true, //Feature control DataTables' server-side processing mode.
    "order": [], //Initial no order.
    "ajax": {
        "url": "http://oss-dev.forexworld.us/oss/user/ajax_receiving",
        "type": "POST",
        data: {
            'csrf_test_name' : '802daa2efaf69edb83b571d7bf7510aa' 
            },
       dataSrc: function ( json ) {
           if(json.csrf_test_name !== undefined) $('meta[name=csrf_test_name]').attr("content", json.csrf_token);
           return json.data;
       }
    },
    "columnDefs": [
    { 
        "targets": [ 0 ], //first column / numbering column
        "orderable": false, //set not orderable
    },
    ],

});

});

</script>

我可以通过将 $config['csrf_regenerate'] = TRUE; 设置为 FALSE 来使我的数据表工作,但我不希望这样。我的猜测是 dataSrc 部分不起作用,但我不确定。

你可以看到它的实际效果 here .

非常感谢任何帮助。谢谢!

最佳答案

Refresh CSRF token on AjaxPOST Datatables: CodeIgniter

以上声明是不言自明的,意思很明确:

我们必须在发出任何 AjaxPOST 请求之前刷新我们的 CSRF token

So, How we will Refresh CSRF Token in CodeIgniter & What is the meaning ff Refresh CSRF in CodeIgniter.


CSRF tokens are only required when you are making a POST requests (ajax post or normal form based post)


Alternatively, you will require to have new CSRF token & hash value before making any AjaxPOST requests. Once Ajax call is done you must update the token and hash value settings in your html or save as variable in your javascript code.


Alternatively, you can exclude the required url from CSRF (You can tell CodeIgniter "Dear CodeIgniter listen, When I will use this url, you are not allowed to check CSRF token and never asked me to attach/send CSRF token within request. Understood? Yes Master) using the config element $config['csrf_exclude_uris'] = array('controller/method', '...');


Alternatively, you can set long time period to expire CSRF token using the config element $config['csrf_expire'] = 300;. Here it is 5 minutes defined to expire the CSRF token, Before the expire time (which start with first POST timestamp) you can use old CSRF token which was generated by CodeIgniter, when you had triggered the first POST request. If no POST request triggered then after first POST request within 5 minutes, CodeIgniter will expire the existing CSRF token and after that you would need to get New CSRF Token again. Sounds Complex.. Not a problem

假设您重新加载页面并且 CodeIgniter 设置了新的 CSRF 哈希,您可以使用它来发出 AjaxPOST 请求。但如果不发出任何请求或重新加载页面,5 分钟后,旧的 CSRF 将过期。现在,如果您再次调用 AjaxPOST 请求,您会在响应中收到 500/403 错误。这意味着 CodeIgniter 使旧的 CSRF 哈希过期,因为您在 CSRF 过期时间(5 分钟)内没有再次发出任何请求,之后当您发送带有旧 CSRF token 的 HTTP POST 请求时,它实际上已经消失了......清除 :)

So, what we can do to get new CSRF token when making an AjaxPOST..?

  • 嗯,对于 GET 请求,您不需要发送任何 CSRF token 。
  • 但是对于 POST 是的!如果你是,你必须在 AjaxPOST 中发送 CSRF 使用 CodeIgniter CSRF 安全 $config['csrf_protection'] = 真;

背后的逻辑是,在使用 GET 进行任何 AjaxPOST 之前获取新的 CSRF 哈希。将其设置在 DOM 中的某处或附加到您的 AjaxSetup 中。

我是 CodeIgniter 的新手.. :( 你有什么例子吗..?

(Bulma!!为什么你又撞了我的车...)是的,当然!!! :)

这是查看 Html 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    
    <meta charset="utf-8">
    <meta name="<?=$this->security->get_csrf_token_name()?>" content="<?=$this->security->get_csrf_hash()?>"/>

    <title>CodeIgniter CSRF Refresh Demo</title>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

    <script type="text/javascript">

    // Set CodeIgniter base_url in JavaScript var to use within
    var _BASE_URL_ = "<?=base_url()?>";
    var _CSRF_NAME_ = "<?=$this->security->get_csrf_token_name()?>";

    (function($) {
        /**
         * New jQuery function to set/refresh CSRF token in Body & to attach AjaxPOST
         * @param  {[type]} $ [description]
         * @return {[type]}   [description]
         */
         $.fn.CsrfAjaxSet = function(CsrfObject) {
            // getting meta object from body head section by csrf name
            var CsrfMetaObj = $('meta[name="' + _CSRF_NAME_ + '"]'),
            CsrfSecret = {};
            // if CsrfObject not set/pass in function
            if (typeof CsrfObject == 'undefined') {
                // assign meta object in CsrfObject
                CsrfObject = CsrfMetaObj;
                // get meta tag name & value
                CsrfSecret[CsrfObject.attr('name')] = CsrfObject.attr('content');
            }
            // CsrfObject pass in function
            else {
                // get Csrf Token Name from JSON
                var CsrfName = Object.keys(CsrfObject);
                // set csrf token name & hash value in object
                CsrfSecret[CsrfName[0]] = CsrfObject[CsrfName[0]];
            }
            // attach CSRF object for each AjaxPOST automatically
            $.ajaxSetup({
                data: CsrfSecret
            });
        };
        /**
         * New jQuery function to get/refresh CSRF token from CodeIgniter
         * @param  {[type]} $ [description]
         * @return {[type]}   [description]
         */
         $.fn.CsrfAjaxGet = function() {
            return $.get(_BASE_URL_ + 'Csrfdata', function(CsrfJSON) {
                $(document).CsrfAjaxSet(CsrfJSON);
            }, 'JSON');            
        };
    })(jQuery);

    // On DOM ready attach CSRF within AjaxPOST
    $(document).CsrfAjaxSet();

</script>
</head>
<body>
<button class="button">Click Me to Trigger AjaxPOST</button>
    <script type="text/javascript">
        // on DOM ready
        $(document).ready(function(){
            // my button 
            $btn = $('.button');
            // on button click
            $btn.on('click', function(e){
                // stop default event
                e.preventDefault();
                // trigger refresh csrf token
                var CSRF = $(document).CsrfAjaxGet();
                // use callback to put your AjaxPOST & Done!
                CSRF.success(function(){
                    $.ajax({
                        url: _BASE_URL_ + 'Controller/Method',
                        method: 'POST',
                        success: function(data){
                            alert('Success');
                        },
                        error: function(xhr, status, error){
                            alert(error);
                        }
                    });
                });
            });
        });
    </script>
</body>
</html>

这是 Controller :

<?php 

(defined('BASEPATH') or exit('No direct script access allowed'));

/**
 * Class Csrfdata to return fresh CSRF hash value
 */
class Csrfdata extends CI_Controller
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Return CodeIgniter CSRF name & Hash on request
     * @return [type] [description]
     */
    public function index()
    {
        if ($this->input->get()) {
            $csrf = array();
            $csrf_name = $this->security->get_csrf_token_name();
            $csrf_hash = $this->security->get_csrf_hash();
            $csrf[$csrf_name] = $csrf_hash;
            echo json_encode($csrf);
        }

    }

}

/* End of file Csrfdata.php */
/* Location: ./application/controllers/Csrfdata.php */

希望您喜欢这个答案和任何建议,非常感谢您的评论...一如既往..:D

关于javascript - 刷新 AjaxPOST 数据表上的 CSRF token : CodeIgniter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44733693/

相关文章:

javascript - 如何呈现一个安全的、仅 HTTP 的 cookie 作为不记名 token (没有 Angular.JS)?

javascript - 在 Facebook JavaScript SDK 中仅从每个相册中提取一张照片?

javascript - Div 无法放入其容器内,并且它们添加了像素。

php - 作为 JavaScript 数组名称的变量

php - 如何将 db 中两个表中的数据路由、获取和显示到 laravel 5.2 中的单个网页

jQuery 数据表使用 OR 运算符按多列搜索

javascript - 无法在 eventReceived 事件中为 Angular 中的事件设置 ID

php - Paypal IPN 变量问题

JQuery ResponsiveSlides 图像 slider

php - Jquery Ajax 未正确接收 php 响应