CodeIgniter 和 CSRF

Posted

技术标签:

【中文标题】CodeIgniter 和 CSRF【英文标题】:CodeIgniter & CSRF 【发布时间】:2018-04-19 22:08:21 【问题描述】:

当用户登录后,他可以用一个小表单进行搜索。这是对控制器的 AJAX 请求。我可以多次执行此操作。但是,当我尝试重新加载页面时,用户已注销,需要重新登录。

这是我的 JS:

var CFG = 
        url: '<?php echo $this->config->item('base_url'); ?>',
        token: '<?php echo $this->security->get_csrf_hash(); ?>'
;


$(function() 


    $('#personen_search_result').hide();
    $('#search_alert').hide();

    $.ajaxSetup(
    
        data: 
        
            token:CFG.token
        
    );

    $(document).ajaxSuccess(function(e,x)
    
        var result = $.parseJSON(x.responseText);
        $('input:hidden[name="token"]').val(result.token);
        $.ajaxSetup(
        
            data: 
            
                token: result.token
            
        );
    );


    $( "#submit_personen" ).click(function(event) 
    


        event.preventDefault();

        var namelast        = $('#namelast').val();
        var dateofbirth     = $('#dateofbirth').val();
        var rijksregisternr = $('#rijksregisternr').val();
        var email           = $('#email').val();
        var hosid           = <?php echo $this->session->hosid; ?>;


        $.ajaxSetup(
        
            data:
            
                nameLast: namelast,
                dateofBirth: dateofbirth,
                rijksregisterNr: rijksregisternr,
                email: email, 
                hosid: hosid
            
        );

        $('#table_personen').html("");
        $('#search_alert').html("").hide();

        $.post(CFG.url + 'persoon/js_retrieve', function(data)
        

            if(data['status']   == 200)
            
                var personenrows        = data['html'];
                $('#table_personen').append (personenrows);

                if (!$('#personen_search_result').is(':visible'))
                    $('#personen_search_result').slideToggle();
            
            else if (data['status'] == 400)
            
                var message         = data['html'];
                $('#search_alert').append(message);

                if (!$('#search_alert').is(':visible'))
                    $('#search_alert').slideToggle();
            
        , 'json');


    );
);

这是我的控制器:

public function js_retrieve()


    // Data preperations

    // Query Builder



    if ($result->num_rows() == 0)
    

        // No result: error message
        $data['html']       = '<span class="alert">Geen personen gevonden.</span>';
        $data['status']     = 400;
    
    else
    

        // Good result, show list in table
        // table header 
        $html               = '<thead class="thead-light"><tr><th>Naam</th>th>Voornaam</th><th>Geboortedatum</th><th>Rijksregister</th><th>status</th></tr><tbody>';

        // create rows
        foreach ($result->result_array() as $row)
        
            $html           .= 
                '<tr>/\n<td><a href="'. base_url( 'persoon/detail/' .$row['id']  ) .'">' . $row['NameLast'] .', '. $row['NameFirst'] . '</a></td>/\n<td>' . $row['DateofBirth'] . '</td>/\n<td>' . $row['RijksRegisterNumber'] . '</td>/\n<td>' . $row['Status'] . '</td></tr>';
        

        // close body
        $data['html']       = $html . '</tbody>';

        // status
        $data['status']     = 200;
    



    // Set CSRF token hash & headers        
    $data['oldtoken']       = $this->input->post('token');
    $data['token']          = $this->security->get_csrf_hash();

    if (!headers_sent())
    
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: ' . date('r'));
        header('Content-type: application/json');
    

    // return result
    exit( json_encode($data , JSON_FORCE_OBJECT) );

谁能给我一些指导?

PS:这些是我的配置:

$config['csrf_token_name'] = 'token';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = FALSE;
$config['csrf_exclude_uris'] = array();

【问题讨论】:

您可以尝试在您的 jQuery 请求中添加 withCredentials: true 吗?应该用那个标志来处理 如果您重新加载页面而不执行任何 AJAX 调用,它是否也要求提供登录凭据?知道这将隔离问题并排除整个 AJAX 问题。 这就是$config['csrf_regenerate']=FALSE; 选项在每次提交时禁用令牌再生。但是,请谨慎行事。这可能会使您面临某些类型的攻击。\ 我添加了 withCredentials: $.ajaxSetup( data: token:CFG.token , xhrFields: withCredentials: true , crossDomain: true );但问题仍然存在。没有 ajax 请求,我可以安全地重新加载页面而无需重新登录 尝试从您的 js_retrieve() 方法中删除 header('Cache-Control: no-cache, must-revalidate'); 【参考方案1】:

这不是一个答案,因为它是一个故障排除测试,太长了,无法发表评论。试试这个:

$this->output->set_header('Cache-Control: no-store, no-cache, must-revalidate');
$this->output->set_content_type('application/json');
$this->output->set_output(json_encode($data, JSON_FORCE_OBJECT));
$this->output->_display();
exit;

【讨论】:

以上是关于CodeIgniter 和 CSRF的主要内容,如果未能解决你的问题,请参考以下文章

Codeigniter 表单发布和验证

使用 jcrop 和 CodeIgniter 裁剪图像

Codeigniter:MySQL Where 子句和引号

PHP实战002:CodeIgniter安装和入门使用

Codeigniter、Restful API 和如何使用密钥

codeigniter和laravel框架