This post is also available in:
English
(CSRF) adalah cara untuk mengelabui server bahwa permintaan yang dikirim ke sana adalah sah sementara itu sebenarnya merupakan upaya yang tidak sah.
Di CodeIgniter, perlindungan CSRF tidak diaktifkan secara default.
Jika diaktifkan maka CodeIgniter menghasilkan hash untuk setiap pengguna aktif dan ini digunakan untuk memverifikasi permintaan.
Perlu mengirim hash dengan permintaan AJAX jika tidak, itu memberikan kesalahan – “Tindakan yang Anda minta tidak diizinkan.”.
Dalam tutorial ini, saya menunjukkan bagaimana Anda dapat mengaktifkan perlindungan CSRF dan membuat ulang hash untuk permintaan AJAX berikutnya dan meneruskan hash dalam permintaan AJAX di proyek CodeIgniter.
Contents
- Table structure
- Configuration
- Model
- Controller
- View
1. Table structure
Dalam contoh ini, saya menggunakan tabel pengguna dan menambahkan beberapa catatan –
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;
2. Configuration
Enable CSRF protection –
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
- Setel TRUE the $config[‘csrf_protection’], ini akan mengaktifkan CSRF.
- Anda dapat mengubah nilai $config[‘csrf_token_name’] default yang disetel ke ‘csrf_test_name’. Saya mengubahnya menjadi ‘csrf_has_name’. Nama ini digunakan dalam permintaan AJAX untuk meneruskan hash.
- Setel TRUE the $config[‘csrf_regenerate’] jika Anda ingin membuat ulang hash CSRF setelah setiap permintaan AJAX, jika tidak, setel FALSE.
Buka application/config/database.php dan tentukan koneksi Database.
$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
Buka application/config/routes.php dan edit nilai default_controller ke User.
$route['default_controller'] = 'User';
Load Database
Untuk mengakses database MySQL, perlu memuat library database.
Buka application/config/autoload.php dan tambahkan database di library array().
$autoload['libraries'] = array("database");
3. Model
Buat file Main_model.php di direktori application/models/ .
Buat metode getUserDetails() yang menggunakan satu parameter.
Periksa apakah $postData[‘username’] disetel atau tidak. Jika disetel, ambil data dari tabel pengguna tempat namapengguna=$postData[‘namapengguna’].
Menampilkan $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; } }
4. Controller
Buat file User.php di direktori application/controllers/.
Buat 2 metode –
- index – Muat pembantu url dan tampilan pengguna_tampilan.
- userDetails – Metode ini digunakan untuk menangani permintaan AJAX dan mengembalikan respons.
Baca nilai POST dan tetapkan di $postData. Muat Main_model Model dan panggil metode getUserDetails() yang meneruskan $postData.
Tetapkan nilai pengembalian di $data dan baca hash CSRF baru dengan memanggil $this->security->get_csrf_hash() untuk permintaan AJAX berikutnya dan tetapkan di $data[‘token’].
Menampilkan $data Array dalam format JSON.
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); } }
5. View
Buat file user_view.php di direktori application/views/ .
Buat elemen teks dan simpan nama token yang ditentukan dalam file aplikasi/config.php di atribut nama menggunakan <?= $this->security->get_csrf_token_name(); ?>. Simpan hash CSRF dalam elemen dengan memanggil <?= $this->security->get_csrf_hash(); ?>.
Menambahkan beberapa nama pengguna di <select > <option>. Nama pengguna yang digunakan di nilai <option > .
Untuk menampilkan detail pengguna yang dipilih, <span > elemen dibuat.
Skrip –
Tentukan perubahan acara di pemilih #sel_user.
Baca atribut nama dari pemilih .txt_csrfname dan tetapkan dalam variabel csrfName. Tetapkan nilai pemilih .txt_csrfname di variabel csrfHash.
Tetapkan nilai opsi yang dipilih dalam variabel nama pengguna.
Kirim permintaan AJAX POST ke ‘<?=base_url()?>index.php/User/userDetails’ where pass {username:username,[csrfName]:csrfHash } sebagai data.
Di sini, hash akan diteruskan seperti – [csrfName]: csrfHash.
Saat panggilan balik berhasil, baca token dari respons dan perbarui nilai .txt_csrfname selector.
Ulangi respons[0] dan perbarui <span > teks elemen.
Completed Code
<!doctype html> <html> <head> <title>How to Send AJAX request with CSRF token in CodeIgniter 3</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.6.0/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>