How to Send AJAX request with CSRF token in CodeIgniter
In CodeIgniter, CSRF security isn't empowered as a matter of course.
In the event that it is been empowered, at that point CodeIgniter creates a hash for every dynamic client and this is utilized to confirm the solicitation.
Require to send the hash with the AJAX demand else, it gives mistake – "The activity you have mentioned isn't permitted.".
Also Read:-How to Upload Image and Create Thumbnail in CodeIgniter
Right now, show how you can empower CSRF insurance and recover hash for next AJAX solicitation and pass hash in AJAX demand in the CodeIgniter venture.
- Table structure
Right now, am utilizing clients table and included a few records –
CREATE TABLE `users` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` varchar(80) NOT NULL,
`username` varchar(80) NOT NULL,
`gender` varchar(10) NOT NULL,
`email` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- Setup
Empower CSRF assurance –
Open application/config/config.php file and update the values of $config['csrf_protection'], $config['csrf_token_name'], and $config['csrf_regenerate'] like this –
$config['csrf_protection'] = TRUE; // Enable CSRF
$config['csrf_token_name'] = 'csrf_hash_name'; // Token name (You can update it)
$config['csrf_regenerate'] = TRUE; // Set TRUE to regenerate Hash
- Set TRUE the $config['csrf_protection'], this will empower CSRF.
- You can change the estimation of $config['csrf_token_name'] default it is set to 'csrf_test_name'. I transformed it to 'csrf_has_name'. This name is utilized in AJAX solicitation to pass the hash.
- Set TRUE the $config['csrf_regenerate'] in the event that you need to recover CSRF hash after every AJAX demand in any case set it FALSE.
Also Read:-How to install Atom editor in Ubuntu
Open application/config/database.php and characterize the Database association.
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root', // Username
'password' => '', // Password
'database' => 'tutorial', // Database name
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
Default controller
Open application/config/routes.php and alter default_controller incentive to User.
$route['default_controller'] = 'User';
Burden Database
Also Read:-How to Export Data in Excel format in Codeigniter using PHPExcel Library
To get to the MySQL database require stacking database library.
Open application/config/autoload.php and include the database in libraries exhibit().
$autoload['libraries'] = array("database");
- Model
Make a Main_model.php record in the application/models/registry.
Make getUserDetails() technique which takes a solitary parameter.
Check if $postData['username'] is set or not. Whenever set at that point get a record from clients table where username=$postData['username'].
Return the $response Array.
Completed Code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Main_model extends CI_Model {
function getUserDetails($postData){
$response = array();
if(isset($postData['username']) ){
// Select record
$this->db->select('*');
$this->db->where('username', $postData['username']);
$q = $this->db->get('users');
$response = $q->result_array();
}
return $response;
}
}
- Controller
Make User.php document in application/controllers/registry.
Make 2 strategies –
- index – Load url partner and user_view see.
- userDetails – This strategy is utilized to deal with the AJAX solicitation and return a reaction.
Also Read:-How to Send emails with EmberJS, Amazon SES And Firebase
Peruse POST esteems and allot in $postData. Burden Main_model Model and call getUserDetails() technique where pass $postData.
Dole out return an incentive in $data and read the new CSRF hash by calling $this->security->get_csrf_hash() for next AJAX ask for and appoint in $data['token'].
Return $data Array in JSON position.
Completed Code
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class User extends CI_Controller {
public function index(){
// load base_url
$this->load->helper('url');
// load view
$this->load->view('user_view');
}
public function userDetails(){
// POST data
$postData = $this->input->post();
// load model
$this->load->model('Main_model');
// get data
$data = $this->Main_model->getUserDetails($postData);
// Read new token and assing in $data['token']
$data['token'] = $this->security->get_csrf_hash();
echo json_encode($data);
}
}
- View
Make user_view.php document in application/sees/catalog.
Make a book component and store token name which is indicated in application/config.php record in name trait utilizing <?= $this->security->get_csrf_token_name(); ?>. Store CSRF hash in the component by calling <?= $this->security->get_csrf_hash(); ?>.
Included some client names in the <select > <option>. Utilized username in the <option > esteem.
Also Read:-Load Data on Page Scroll in CodeIgniter using jQuery and Ajax Load Data on Page Scroll in CodeIgniter using jQuery and Ajax
To show chosen client subtleties made <span > components.
Script –
Characterize change occasion on #sel_user selector.
Peruse name quality of .txt_csrfname selector and relegate in csrfName variable. Dole out .txt_csrfname selector esteem in csrfHash variable.
Dole out chosen alternative incentive in username variable.
Send AJAX POST solicitation to '<?=base_url()?>index.php/User/userDetails' the place pass {username:username,[csrfName]:csrfHash } as information.
Here, hash will pass like – [csrfName]: csrfHash.
On effective callback read the token from reaction and update the .txt_csrfname selector esteem.
Circle on the response[0] and update <span > components content.
Also Read:-Login with Facebook in CodeIgniter using JavaScript SDK
Completed Code
<!doctype html>
<html>
<head>
<title>How to Send AJAX request with CSRF token in CodeIgniter</title>
</head>
<body>
<!-- CSRF token (Here, name is 'csrf_hash_name' which is specified in $config['csrf_token_name'] in cofig.php file ) -->
<input type="text" class="txt_csrfname" name="<?= $this->security->get_csrf_token_name(); ?>" value="<?= $this->security->get_csrf_hash(); ?>"><br>
Select Username : <select id='sel_user'>
<option value='yssyogesh'>yssyogesh</option>
<option value='sonarika'>sonarika</option>
<option value='vishal'>vishal</option>
<option value='sunil'>sunil</option>
</select>
<!-- User details -->
<div >
Username : <span id='suname'></span><br/>
Name : <span id='sname'></span><br/>
Email : <span id='semail'></span><br/>
</div>
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type='text/javascript'>
// baseURL variable
var baseURL= "<?= base_url();?>";
$(document).ready(function(){
$('#sel_user').change(function(){
// CSRF Hash
var csrfName = $('.txt_csrfname').attr('name'); // Value specified in $config['csrf_token_name']
var csrfHash = $('.txt_csrfname').val(); // CSRF hash
// Username
var username = $(this).val();
// AJAX request
$.ajax({
url:'<?=base_url()?>index.php/User/userDetails',
method: 'post',
data: {username: username,[csrfName]: csrfHash },
dataType: 'json',
success: function(response){
// Update CSRF hash
$('.txt_csrfname').val(response.token);
// Empty the elements
$('#suname,#sname,#semail').text('');
// Loop on response
$(response[0]).each(function(key,value){
var uname = value.username;
var name = value.name;
var email = value.email;
$('#suname').text(uname);
$('#sname').text(name);
$('#semail').text(email);
});
}
});
});
});
</script>
</body>
</html>
Also Read:-How to Setup Maintenance Mode in CodeIgniter
- Conclusion
On the off chance that you would prefer not to recover hash for each AJAX, at that point set FALSE to $config['csrf_regenerate'] in config.php document. Right now, new hash will be created by the CSRF expiry time set.