skip to Main Content

I have a codeigniter4 application.
When i set public $regenerate = true; in Security.php
the view with a form submit to add employee redirects to itself on submit. But when regenerate is false, code submits to the controller and data is processed as required
How can i solve the issue with regenerate set to true?.

The controller function handling add_employee is:

public function add_employee()
    {
        $session = session();
        $request = ConfigServices::request();
        $db = ConfigDatabase::connect();
       
        $usermodel = new AppModelsUserModel();
        $data['user']=$usermodel->getRow($session->get('email'));
        $data['title'] = 'Add employee';

        $employeemodel = new AppModelsEmployeeModel();
        $divisionmodel = new AppModelsDivisionModel();
        $userRoleModel = new AppModelsUserRoleModel();

        $data['employee'] = $employeemodel->getAll();
        $data['designation'] = $employeemodel->getAllDesignations();
        $data['division'] = $divisionmodel->findAll();
        $data['roles']  = $userRoleModel->findAll();
        
        
         $role_id= $data['user']['role_id'];
        if($role_id==5||$role_id==10){ //Division Admin or Division head

         $builder=$db->table('tbl_division');
         $builder->select('tbl_division.int_divisionID');

             if($role_id==5){         
            
                 $builder->join('tbl_administrator','tbl_administrator.int_divisionID=tbl_division.int_divisionID');
            } else{
                $builder->join('tbl_employee','tbl_employee.int_divisionID=tbl_division.int_divisionID');
            }

         $division=$builder->get()->getRowArray();
         $data['selected_division'] = $division['int_divisionID'];

         $builder=$db->table('tbl_department');
         $builder->select('tbl_department.int_departmentID,tbl_department.vchr_departmentName');
         $builder->where('tbl_department.int_divisionID',$division['int_divisionID']);
         $data['department']= $builder->get()->getResultArray();
        }
         elseif($role_id==11)//Department Head
         {
          $builder=$db->table('tbl_employee');
          $builder->select('int_departmentID');          
          $builder->where('tbl_employee.int_userID',$data['user']['id']);
          $department = $builder->get()->getRowArray();          
          $department_id = $department['int_departmentID'];
          $data['department_id']=$department_id;

          $builder=$db->table('tbl_department');
          $builder->select('tbl_department.int_divisionID');
          $builder->where('tbl_department.int_departmentID',$department_id);
          $division=$builder->get()->getRowArray();
          $data['selected_division'] = $division['int_divisionID'];

          $builder=$db->table('tbl_department');          
          $builder->select('tbl_department.id,tbl_department.int_departmentID,tbl_department.vchr_departmentName');
          $builder->where('tbl_department.int_divisionID',$division['int_divisionID']);
          $data['department']= $builder->get()->getResultArray();
         }

        
        if ($this->request->getMethod() == "post") {

            
             $validation =  ConfigServices::validation();

             $_POST['csrf_test_name']=$_REQUEST['csrf_test_name'];

             $rules = [
           
                    "csrf_test_name" => [
                        "label" => "CSRF Token Name",
                        "rules" => "required|trim|alpha_numeric|max_length[64]"
                    ],
                    "vchr_CDIT_employeeID" => [
                        "label" => "CDIT EmployeeID",
                        "rules" => "required|trim|alpha_numeric|max_length[10]"
                    ],
                    "vchr_employeeName" => [
                        "label" => "Employee Name",
                        "rules" => "required|trim|alpha_space|max_length[100]"
                    ],
                    "vchr_email_id" => [
                        "label" => "Email",
                        "rules" => "required|trim|valid_email|max_length[100]"
                    ],
                    "int_mobileNo" => [
                        "label" => "Mobile No",
                        "rules" => "required|trim|numeric|max_length[10]|min_length[10]"
                    ],
                    "int_empType" => [
                        "label" => "Mobile No",
                        "rules" => "required|trim|numeric|max_length[3]"
                    ]
                    
                ];

                 $int_empType = $request->getPost('int_empType');
      
      
      if(!($int_empType==7 || $int_empType==8)){


        $rules1= [
            "int_designationID" => [
                        "label" => "Designation",
                        "rules" => "required|trim|numeric|max_length[4]"
                    ],
            "int_divisionID" => [
                        "label" => "Division",
                        "rules" => "required|trim|numeric|max_length[4]"
                    ]

        ];

        $rules=array_merge($rules,$rules1);
        
        }

        if(!($int_empType==7 || $int_empType==8 || $int_empType==9 )){

        
        $rules1= [
            "int_departmentID" => [
                        "label" => "Department",
                        "rules" => "required|trim|numeric|max_length[4]"
                    ]

        ];

         $rules=array_merge($rules,$rules1);

        }
       
        if (!($this->validate($rules))) {   

                $session->setFlashdata('employeemessage', '<div class="alert alert-danger" role="alert">
                Validation Errors!</div>');
           
                return redirect()->back()->withInput();
           
            } 
        else{
                
                $email = strip_tags($request->getPost('vchr_email_id'));
                $name = strip_tags($request->getPost('vchr_employeeName'));

         

          $employeeemailexists = $employeemodel->where('vchr_email_id',$email)->first();
          
          if($employeeemailexists){

             $session->setFlashdata('employeemessage', '<div class="alert alert-danger" role="alert">
             employee Creation Failed. employee with this email already exists</div>');
             return redirect()->to('employee');
            
          }

          $userdata  = $usermodel->where('email',$email)->first();
          if($userdata){

            $session->setFlashdata('employeemessage', '<div class="alert alert-danger" role="alert">
             User Creation Failed. User with this email already exists</div>');
             return redirect()->to('employee');
            
          }
          $date_created = date("Y-m-d H:i:s", time());

          $comb = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_-";
          $shfl = str_shuffle($comb);
          $pwd = substr($shfl,0,12);
          $data = [
              'name' => $name,
              'email' => $email,
              'image' => 'default.jpg',
              'password' => md5($pwd),
              
              'role_id' => 4,
              'is_active' => 1,
              'isFirstLogin' => 1,
              'date_created' => $date_created
          ];

         $token = base64_encode(random_bytes(32));

         
          $emailstatus=sendemail($name,$email,$token,$pwd, 'verify');

          if(!$emailstatus){
               
                $emailmsg='<span class="alert alert-danger" role="alert">Password couldnot be send through email.Check mail configuration</span>';

            }
            else
                $emailmsg='<span class="alert alert-success" role="alert"> Password send to employee email </span>';
           $usermodel->insert($data);
          
           $res=$usermodel->where('email',$email)->first();

            $insert_id=$res['id'];

            $employeemodel->saveToDB($insert_id);

            $session->setFlashdata('employeemessage', '<div class="alert alert-success" role="alert">
                Employee added successfully!.Password is <b>'.$pwd.'</b></div>'.$emailmsg);
                return redirect()->to('employee');
            }
        }
        else{
            echo view('templates/admin_header', $data).
            view('templates/admin_sidebar').
            view('templates/admin_topbar', $data).
            view('employee/add_employee').
            view('templates/admin_footer');
        }

      
    }

My view add_employee

<!-- Begin Page Content -->

<div class="container-fluid">

    <!-- Page Heading -->
    <h1 class="h3 mb-4 text-gray-800">Add Employees </h1>

    <div class="card shadow mb-3">
        <!--<div class="card-header">
            Add Employees
        </div>-->

        <div class="card-body">
        <div style="display: flex; justify-content: flex-end"> <button  onclick="history.back();"><i class="fas fa-arrow-left"></i> Back</button>
            </div>
          <?php
          $attributes = array('id' => 'myform');
          echo form_open('employee/add_employee',$attributes);?>


                <div class="form-group">
                    <label for="vchr_CDIT_employeeID">CDIT Employee ID<font color="red"> *</font></label>
                    <input class="form-control" maxlength="100" 
                    type="text" name="vchr_CDIT_employeeID" placeholder="Enter CDIT Employee ID"
                    value="<?= set_value('vchr_CDIT_employeeID'); ?>">
                    <?= form_error('vchr_CDIT_employeeID', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>


                <div class="form-group">
                    <label for="vchr_employeeName">Employee Name<font color="red"> *</font></label>
                    <input class="form-control" maxlength="100" 
                    type="text" name="vchr_employeeName" placeholder="Enter Employee Name" value="<?= set_value('vchr_employeeName'); ?>">
                    <?= form_error('vchr_employeeName', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>


                <div class="form-group">
                    <label for="vchr_email_id">E-Mail ID<font color="red"> *</font></label>
                    <input class="form-control" maxlength="100" 
                    type="email" name="vchr_email_id" placeholder="Enter Email ID" value="<?= set_value('vchr_email_id'); ?>">
                    <?= form_error('vchr_email_id', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>


                <div class="form-group">
                    <label for="int_mobileNo">Mobile Number<font color="red"> *</font></label>
                    <input class="form-control"
                    type="text" minlength="10" maxlength="10" name="int_mobileNo" placeholder="Enter Mobile Number" value="<?= set_value('int_mobileNo'); ?>">
                    <?= form_error('int_mobileNo', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>
                
                <div class="form-group">
                    <label for="int_empType">Enter Employee Type <font color="red"> *</font></label>
                    <select name="int_empType" id="int_empType" class="form-control">
                      <option value="">---Select Role---</option>
                      <?php foreach ($roles as $r) : ?>
                      <?php 
                     
                     if(!in_array($r['id'],[1,3,5]))
                      {
                      
                      ?><option value="<?= $r['id']; ?>"><?= $r['role']; ?></option>
                    <?php } endforeach; ?>
                      </select>
                      <?= form_error('int_empType', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>

                <div class="form-group" id="divisionDiv">
                    <label for="int_divisionID">Enter Division <font color="red"> *</font></label>
                    <select name="int_divisionID" id="int_divisionID" class="form-control"
                    
                    >
                    
                     <?php if(isset($selected_division)) { 
                     foreach ($division as $d) :
                     if($d['int_divisionID']==$selected_division){
                     ?>
                    >
                     <option value="<?= $d['int_divisionID']; ?>" selected > <?= $d['vchr_divisionName']; ?></option>
                    <?php
                    } endforeach;
                    } else {
                    ?>
                    
                    
                        <option value="">---Select Division---</option>
                        <?php foreach ($division as $d) : ?>
                        <option value="<?= $d['int_divisionID']; ?>"                     
                        >
                        <?= $d['vchr_divisionName']; ?></option>
                        <?php endforeach; }?>
                    </select>
                    <?= form_error('int_divisionID', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>

                <div class="form-group" id="deptdiv">
                    <label for="int_departmentID">Enter Department <font color="red"> *</font></label>
                    <select name="int_departmentID" id="int_departmentID" class="form-control">
                    <?php if(isset($department_id)) { 
                     foreach ($department as $d) :
                     if($d['int_departmentID']==$department_id){
                     ?>
                   
                     <option value="<?= $d['int_departmentID']; ?>" selected > <?= $d['vchr_departmentName']; ?></option>
                    <?php
                    } endforeach;
                    } else {
                    ?>
                        <option value="" selected>---Select Department---</option>
                        <?php if(isset($department)){
                         foreach ($department as $d) : ?>
                        <option value="<?= $d['int_departmentID']; ?>">
                        <?= $d['vchr_departmentName']; ?></option>
                        <?php endforeach; }
                        
                        }?>

                    </select>
                    <?= form_error('int_departmentID', '<small class="text-danger pl-3">', '</small>'); ?>
                </div>
                <div class="error" width="100%"></div>


                <div class="form-group" id="desigDiv">
                    <label for="int_designationID">Enter Designation <font color="red"> *</font></label>
                    <select name="int_designationID" id="int_designationID" class="form-control">
                        <option value="">---Select Designation---</option>

                    </select>
                    <?= form_error('int_designationID', '<small class="text-danger pl-3">', '</small>'); ?>

                </div>
                <div class="error" width="100%"></div>


                <!-- button save -->
                  <div class="form-group">
                        <button type="submit" class="btn btn-success" >Add Employee!</button>
                    </div>
            </form>
        </div>

        <div class="card-footer small text-muted">
        <font color="red"> *</font> must be filled
        </div>
    </div>

</div>
<!-- /.container-fluid -->

</div>
<!-- End of Main Content -->

</div>
<!-- /.container-fluid -->

</div>
<!-- End of Main Content -->

<script type="text/javascript">


$('#int_divisionID').on('change', function(){
    var int_divisionID = $('#int_divisionID').val();
   
     var csrfName = "csrf_test_name";
    var csrfHash = $('[name="csrf_test_name"]').val();

    $.ajax({
        type:"POST",
        url: "<?php echo site_url('Department/getDepartments')?>",
        data: {[csrfName]: csrfHash, int_divisionID: int_divisionID},
        success:function(response){

            $('#int_departmentID').html('<option value=""> ---Select Department--- </option>');
            $.each(JSON.parse(response), function(key,val) {
                $('#int_departmentID').append('<option value="' + val.id + '">'+ val.vchr_departmentName +'</option>');
            });
        }
    });


});

$('#int_departmentID').on('change', function(){
    var int_divisionID = $('#int_divisionID').val();
   
     var csrfName = "csrf_test_name";
    var csrfHash = $('[name="csrf_test_name"]').val();
$.ajax({
        type:"POST",
        url: "<?php echo site_url('Department/getDesignations')?>",
        data: {[csrfName]: csrfHash, int_divisionID: int_divisionID},
        success:function(response){

            $('#int_designationID').html('<option value=""> --Select Designation-- </option>');
            $.each(JSON.parse(response), function(key,val) {
                $('#int_designationID').append('<option value="' + val.id + '">'+ val.vchr_designation +'</option>');
            });
        }
    });
});
</script>

<script type="text/javascript">

$(document).ready(function() {

$('#int_empType').on('change', function(){
 var int_empType = $('#int_empType').val();
 if(int_empType==7 || int_empType==8 || int_empType==9 ){
 $('#deptdiv').hide();
 $('#int_departmentID').val(0);
 }
 else{
 $('#deptdiv').show();
 $('#divisionDiv').show();
  $('#desigDiv').show();
 }
 if(int_empType==7 || int_empType==8){
 
  $('#divisionDiv').hide();
  $('#desigDiv').hide();
  $('#int_divisionID').val(0);
  }
  else{
  $('#divisionDiv').show();
  }
 
});

 var int_divisionID = $('#int_divisionID').val();
    
    var csrfName = "csrf_test_name";
    var csrfHash = $('[name="csrf_test_name"]').val();
$.ajax({
        type:"POST",
        url: "<?php echo site_url('Department/getDesignations')?>",
        data: {[csrfName]: csrfHash, int_divisionID: int_divisionID},
        success:function(response){
            $('#int_designationID').html('<option value=""> --Select Designation-- </option>');
            $.each(JSON.parse(response), function(key,val) {
                $('#int_designationID').append('<option value="' + val.id + '">'+ val.vchr_designation +'</option>');
            });
        }
    });

jQuery.validator.addMethod("name_check", function(value, element) {
return this.optional(element) || /^[a-zA-Zs.-]+$/.test(value);
});

jQuery.validator.addMethod("CDIT_employeeID", function(value, element) {
return this.optional(element) || /^[a-zA-Z0-9s.-]+$/.test(value);
});

jQuery.validator.addMethod("email_check", function(value, element) {
return this.optional(element) || /^[a-zA-Z0-9._-]+@([a-zA-Z0-9-]+.[a-zA-Z])*[a-zA-Z0-9-]+.[a-zA-Z]{2,5}$/i.test(value);
});

jQuery.validator.addMethod("phonenumber", function(value, element) {
return this.optional(element) || /^d{10}$/.test(value);
});


$("#myform").validate({

rules: {

vchr_CDIT_employeeID: {

required: true,
CDIT_employeeID:true,

},

vchr_employeeName: {

required: true,
name_check:true,

},

vchr_email_id: {

required: true,
//email_check:true,

},

int_mobileNo: {
required:true,
minlength:10,
maxlength:10,
phonenumber:true,

},

int_divisionID:{
  required: {
                depends: function(element) {
                    return (!($('#int_empType').val()==7 || $('#int_empType').val()==8))
                }
                }

},

int_departmentID :{
  required: {depends: function(element) {
                    return (!($('#int_empType').val()==7 || $('#int_empType').val()==8 ||  $('#int_empType').val()==9))
                }}

},

int_designationID: {
  required: {depends: function(element) {
                    return (!($('#int_empType').val()==7 || $('#int_empType').val()==8 ||  $('#int_empType').val()==9))
                } }
},



int_empType: {
  required:true,
},


},
messages: {

vchr_employeeName: {
required: "<font color='#FF0000'> Employee Name required !!</font>",
name_check:"<font color='#FF0000' > Invalid Special characters in Employee Name!!</font>"
},

vchr_email_id: {
required: "<font color='#FF0000'> E-mail ID is required !!</font>",
//email_check: "<font color='#FF0000'> Invalid Email Format !!</font>",
},

int_mobileNo: {
  required: "<font color='#FF0000'> Mobile Number is required !!</font>",
  minlength : "<font color='#FF0000'> Mobile Number should be of 10 characters long !!</font>",
  maxlength : "<font color='#FF0000'> Mobile Number should be of 10 characters long !!</font>",
  phonenumber : "<font color='#FF0000'> Mobile Number is Invalid !!</font>",
},

vchr_CDIT_employeeID :{
  required: "<font color='#FF0000'> CDIT Employee ID required !!</font>",
  CDIT_employeeID : "<font color='#FF0000'> Invalid Employee ID !!</font>",

},

int_divisionID :{
  required: "<font color='#FF0000'> Division required !!</font>",

},

int_departmentID :{
  required: "<font color='#FF0000'> Department required !!</font>",

},

int_designationID :{
  required: "<font color='#FF0000'> Designation required !!</font>",

},

int_empType : {
  required: "<font color='#FF0000'> Employee Type required !!</font>",

},


},
errorElement: "span",
errorPlacement: function(error, element) {
  error.appendTo(element.parent("div").next());
},
submitHandler: function (form) {
            /*var key = "eTicketingCI4CDIT#$abc";
            var form = document.getElementById("myForm");
            var inputs = form.getElementsByTagName("input");

            for (var i = 0; i < inputs.length; i++) {
                var input = inputs[i];
                if (input.type !== "submit" && input.type !== "button") {
                    var encryptedValue = CryptoJS.AES.encrypt(input.value, key).toString();
                    input.value = encryptedValue;
                }
            }*/
              
              form.submit();
          }

});

});


</script>

The CI4 version is 4.2.12.
My Security.php file:

<?php

namespace Config;

use CodeIgniterConfigBaseConfig;

class Security extends BaseConfig
{
    /**
     * --------------------------------------------------------------------------
     * CSRF Protection Method
     * --------------------------------------------------------------------------
     *
     * Protection Method for Cross Site Request Forgery protection.
     *
     * @var string 'cookie' or 'session'
     */
    public $csrfProtection = 'cookie';

    /**
     * --------------------------------------------------------------------------
     * CSRF Token Randomization
     * --------------------------------------------------------------------------
     *
     * Randomize the CSRF Token for added security.
     *
     * @var bool
     */
    public $tokenRandomize = true;

    /**
     * --------------------------------------------------------------------------
     * CSRF Token Name
     * --------------------------------------------------------------------------
     *
     * Token name for Cross Site Request Forgery protection.
     *
     * @var string
     */
    public $tokenName = 'csrf_test_name';

    /**
     * --------------------------------------------------------------------------
     * CSRF Header Name
     * --------------------------------------------------------------------------
     *
     * Header name for Cross Site Request Forgery protection.
     *
     * @var string
     */
    public $headerName = 'X-CSRF-TOKEN';

    /**
     * --------------------------------------------------------------------------
     * CSRF Cookie Name
     * --------------------------------------------------------------------------
     *
     * Cookie name for Cross Site Request Forgery protection.
     *
     * @var string
     */
    public $cookieName = 'csrf_cookie_name';

    /**
     * --------------------------------------------------------------------------
     * CSRF Expires
     * --------------------------------------------------------------------------
     *
     * Expiration time for Cross Site Request Forgery protection cookie.
     *
     * Defaults to two hours (in seconds).
     *
     * @var int
     */
    public $expires = 7200;

    /**
     * --------------------------------------------------------------------------
     * CSRF Regenerate
     * --------------------------------------------------------------------------
     *
     * Regenerate CSRF Token on every submission.
     *
     * @var bool
     */
    public $regenerate = true;

    /**
     * --------------------------------------------------------------------------
     * CSRF Redirect
     * --------------------------------------------------------------------------
     *
     * Redirect to previous page with error on failure.
     *
     * @var bool
     */
    public $redirect = true;

    /**
     * --------------------------------------------------------------------------
     * CSRF SameSite
     * --------------------------------------------------------------------------
     *
     * Setting for CSRF SameSite cookie token.
     *
     * Allowed values are: None - Lax - Strict - ''.
     *
     * Defaults to `Lax` as recommended in this link:
     *
     * @see https://portswigger.net/web-security/csrf/samesite-cookies
     *
     * @var string
     *
     * @deprecated `ConfigCookie` $samesite property is used.
     */
    public $samesite = 'Lax';
}

2

Answers


  1. Chosen as BEST ANSWER

    Update the csrftoken in the ajax call in onload of Department/getDesignations.

    inside Department/getDesignations I changed the data by added a csrftoken and designation data separately.

    $data['designation']=$designations;
    $data['token']=csrf_hash();
    
    return $this->response->setJSON($data);
    

    At the ajax response side i added the following also

    $('input[name="csrf_test_name"]').val(response.token);
    

  2. OP statement 1

    codeigniter4 code to add employee redirects to itself on submit…

    Explanation 1

    This behavior is expected when you set the $redirect Security property to true.

    Redirection on Failure

    Since v4.3.0, when a request fails the CSRF validation check, it will
    throw a SecurityException by default,

    If you want to make it redirect to the previous page, change the
    following config parameter value in app/Config/Security.php:

    public bool $redirect = true;

    OP statement 2

    But when regenerate is false, code submits to the controller and
    data is processed as required. How can I solve the issue with
    regenerate set to true?

    Explanation 2

    It fails because when the $regenerate Security property is set to true, the CSRF Token is regenerated on every POST, PUT, DELETE, and PATCH submission.

    Token Regeneration

    Tokens may be either regenerated on every submission (default) or kept
    the same throughout the life of the CSRF cookie. The default
    regeneration of tokens provides stricter security, but may result in
    usability concerns as other tokens become invalid (back/forward
    navigation, multiple tabs/windows, asynchronous actions, etc). You may
    alter this behavior by editing the following config parameter value in
    app/Config/Security.php:

    public $regenerate = true;

    Solution

    With that out of the way, this means you will have to update the next submitted CSRF Token on your client (AJAX) on every submission. To manage that, you may send the latest CSRF Token through a Response Header.

    1. STEP 1: Configure your Security settings in your .env file which resides at the root of your project.

      security.csrfProtection = 'session'
      security.tokenRandomize = true
      security.regenerate = true
      security.redirect = true
      
    2. STEP 2: Set an HTML DOM <meta /> element to always hold the latest generated CSRF Token. This may be preferably set in your main HTML template.

    <?php echo csrf_meta("csrf-field") ?>
    
    1. STEP 3: Set up a Filter to manage the need for sending the CSRF Token through a Response Header.

      • app/Config/Filters.php
      <?php
      
      namespace Config;
      
      use CodeIgniterFiltersCSRF;
      use AppFiltersCsrfToken;
      
      // ...
      
      class Filters extends BaseConfig
      {
          public array $aliases = [
              'csrf' => CSRF::class,
              // ...
              'csrfToken' => CsrfToken::class,
          ];
      
          public array $globals = [
              'before' => [
                  // ...
                  'csrf',
                  // ...
              ],
              'after' => [
                  // ...
                  'csrfToken',
              ],
          ];
      
          // ...
      }
      
      • app/Filters/CsrfToken.php
      <?php
      
      namespace AppFilters;
      
      use CodeIgniterFiltersFilterInterface;
      use CodeIgniterHTTPRequestInterface;
      use CodeIgniterHTTPResponseInterface;
      
      class CsrfToken implements FilterInterface
      {
          public function before(RequestInterface $request, $arguments = null)
          {
          }
      
          public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
          {
              $method           = strtoupper($request->getMethod());
              $methodsProtected = ["POST", "PUT", "DELETE", "PATCH"];
      
              if (in_array($method, $methodsProtected, true)) {
                  $response->setHeader(csrf_header(), csrf_hash());
              }
      
          }
      }
      
    2. STEP 4: On your front-end, set up global jQuery AJAX events to automatically handle the sending and updating of the CSRF Token for all CSRF-protected HTTP methods.

      $(document).on("ajaxSend", function (event, jqXHR, ajaxOptions) {
      
         if ((ajaxOptions.method?.toLowerCase() === "post")) {
             jqXHR.setRequestHeader($("#csrf-field").attr("name"), $("#csrf-field").attr("content"));
         }
      
      });
      
      $(document).on("ajaxComplete", function (event, jqXHR, ajaxOptions) {
      
          const csrfToken = jqXHR.getResponseHeader($("#csrf-field").attr("name"));
      
          if ((ajaxOptions.method?.toLowerCase() === "post") && csrfToken) {
              $("#csrf-field").attr("content", csrfToken);
          }
      
      });
      

    Conclusion: With the above setup, you no longer have to manually send a CRSF Token in your AJAX POST request body or pollute your Controller method’s response data. The latest Token will automatically be sent on your behalf from STEP 4.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search