Reputation: 103
Note: This question is not about failing AJAX requests, it is about failing regular form submissions.
I have enabled CSRF protection in CodeIgniter 3, using the following config.php
:
$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;
I am correctly using form_open()
in form fields in order to automatically generate the required hidden fields containing the CSRF tokens. However, when I submit any form on my website it results in the "An Error Was Encountered - The action you have requested is not allowed." error.
Cookie settings:
$config['cookie_prefix'] = '';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;
Session settings:
$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;
Also, contrary to most questions about CI CSRF protection, CSRF tokens in my AJAX request do properly work by adding the following snippet to my initial 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;
}
});
Any way to get my CSRF protection to work in form fields? Also, my csrf_cookie_name
value in the cookie is different from the csrf_token_name
value in the hidden HTML field, is this supposed to happen?
Upvotes: 1
Views: 1550
Reputation: 2151
This is happening because CSRF token getting regenerated on each AJAX request. You can solve this issue by setting $config['csrf_regenerate']
option to FALSE
or you can update csrf token on each AJAX request manually using jquery or javascript.
Check this article for implementation : When CodeIgniter’s CSRF Protection breaks your Ajax
This answer by PaulD is also great.
Upvotes: 2
Reputation: 47
I have come across this issue many times.It's one of those problems that annoys me :)) . The issue seems to be the fact that by making an ajax request to a certain controller regenerates the token so you send the token generated previously,thus causing a token mismatch.I solved my problem by disabling csrf_regenerate.I know it's not as secure but it gets things going.
Upvotes: 0