CodeIgniter CSRF在表单上失败

时间:2018-02-06 12:00:40

标签: php forms codeigniter csrf codeigniter-3

注意:这个问题关于AJAX请求失败,而是关于常规表单提交失败。

我已使用以下config.php

在CodeIgniter 3中启用了CSRF保护
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;

我正在表单字段中正确使用form_open(),以便自动生成包含CSRF令牌的必需隐藏字段。但是,当我在我的网站上提交任何表格时,会导致“遇到错误 - 不允许您请求的操作”。错误。

Cookie设置:

$config['cookie_prefix'] = '';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;

会话设置:

$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 2592000; // one month in seconds
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;

此外,与大多数关于CI CSRF保护的问题相反,我的AJAX请求中的CSRF令牌通过将以下代码段添加到我的初始JavaScript中来正常工作:

function getCookie(c_name) { // A javascript function to get the cookie value
    if(document.cookie.length > 0) {
        c_start = document.cookie.indexOf(c_name + "=");
        if(c_start != -1) {
            c_start = c_start + c_name.length + 1;
            c_end = document.cookie.indexOf(";", c_start);
            if(c_end == -1) c_end = document.cookie.length;
            return unescape(document.cookie.substring(c_start,c_end));
        }
    }
    return "";
}

$.ajaxPrefilter(function(options, originalOptions, jqXHR){ // This function will attach "csrf_test_name" with all the request you are sending.
    if (options.type.toLowerCase() === "post") { // Required only if its a post method
        var csrf_token = getCookie("csrf_cookie_name");
        // initialize `data` to empty string if it does not exist
        options.data = options.data || "";

        // add leading ampersand if `data` is non-empty
        options.data += options.data?"&":"";

        // add _token entry
        options.data += "csrf_token_name=" + csrf_token;
    }
});

如何让我的CSRF保护在表单字段中工作?此外,Cookie中的csrf_cookie_name值与隐藏HTML字段中的csrf_token_name值不同,是否应该发生?

2 个答案:

答案 0 :(得分:1)

这是因为CSRF令牌在每个AJAX请求上重新生成。您可以通过将$ config [' csrf_regenerate']选项设置为FALSE来解决此问题,或者您可以使用jquery或javascript手动更新每个AJAX请求上的csrf令牌。

查看本文的实施:When CodeIgniter’s CSRF Protection breaks your Ajax

answer by PaulD也很棒。

答案 1 :(得分:0)

我多次遇到过这个问题。这些问题之一让我烦恼:))。问题似乎是通过向某个控制器发出ajax请求来重新生成令牌,因此您发送先前生成的令牌,从而导致令牌不匹配。我通过禁用csrf_regenerate解决了我的问题。我知道它不是虽然安全,但它会让事情顺利进行。