我正在尝试使数据表在我的网站中工作。但是当我点击搜索、下一页、排序时,它不起作用。这是因为没有重新生成 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 中看到它。

任何帮助都受到高度赞赏。谢谢!

最佳答案


上述声明是不言自明的,并具有明确的含义:
我们必须在发出任何 AjaxPOST 请求之前刷新我们的 CSRF token









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

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

  • 背后的逻辑是,在使用 GET 进行任何 AjaxPOST 之前获取新的 CSRF 哈希。将其设置在 DOM 中的某个位置或附加到您的 AjaxSetup 中。
    我是 CodeIgniter 的新手 .. :( 你有任何例子吗..?
    ( bool 玛!!为什么你又撞到我的车了......)是的,当然!!! :)
    这里是查看 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/

    10-12 18:20
    查看更多