เขียนโปรแกรมด้วย CodeIgniter การป้องกัน CSRF แล้วเกิดปัญหากับ AJAX เมื่อเปิด csrf_regenerate


PHP CodeIgniter Security Class

https://www.codeigniter.com/user_guide/libraries/security.html

การเขียนโปรแกรมเพื่อความปลอดภัยในการรับข้อมูลจากแบบฟอร์ม ใน CodeIgniter จะต้องเปิด $config['csrf_protection'] = TRUE; ถือว่าเป็นสิ่งจำเป็นที่จะต้องเปิดใช้งาน แต่ถ้าหากต้องการให้โปรแกรมเรา Submit ได้ครั้งเดียว ให้เปิดการป้องกันการรีเฟรช ด้วยการเพิ่ม  $config['csrf_regenerate'] = TRUE; เข้าไปอีกอัน

$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;

แต่ปัญหาคือ เมื่อเปิด $config['csrf_regenerate'] = TRUE; การทำงานของโปรแกรมจะมีปัญหากับการส่งค่าแบบ AJAX ทำให้หน้า Controller ไม่สามารถรับค่าจากแบบฟอร์มได้





สำหรับวิธีการแก้ไขปัญหาคือ จะต้องเขียนโปรแกรมอ่านค่าจาก Cookie มาอีกครั้งเพื่อส่งข้อมูลการเข้ารหัสความปลอดภัยของแบบฟอร์มไปด้วย

ตัวอย่าง

csrf_token_name = '<?php echo $this->security->get_csrf_token_name(); ?>';
csrf_cookie_name = '<?php echo $this->config->item('csrf_cookie_name'); ?>';
$(function ($) {
    // this bit needs to be loaded on every page where an ajax POST 
    var object = {};
    object[csrf_token_name] = $.cookie(csrf_cookie_name);
    $.ajaxSetup({
        data: object
    });
    $(document).ajaxComplete(function () {
        object[csrf_token_name] = $.cookie(csrf_cookie_name);
        $.ajaxSetup({
            data: object
        });
    });
});

โค้ดด้านบนนี้ จะมีการอ่านคุกกี้ มาเก็บไว้อีกครั้งก่อนส่งข้อมูลออกไป

object[csrf_token_name] = $.cookie(csrf_cookie_name);

ซึ่ง csrf_token_name และ csrf_cookie_name ด้านบนนี้ก็จะต้องตรงกับที่เราคอนฟิกไว้

หากท่านใดเขียนโปรแกรมด้วย PHP CodeIgniter เมื่อใช้ AJAX ในแบบฟอร์มแล้วมีปัญหากับ  csrf_regenerate ก็ลองใช้วิธีนี้ดูนะครับ


:: อ้างอิง ::

How to make Ajax work when csrf_regeneration is true in CodeIgniter3?
https://stackoverflow.com/questions/29903517/how-to-make-ajax-work-when-csrf-regeneration-is-true-in-codeigniter3


ความคิดเห็น