codeigniter CSRF error: “The action you have requested is not allowed.”

后端 未结 14 2322
长发绾君心
长发绾君心 2020-11-28 12:57

I enabled the csrf_protection option in codeigniter\'s config file, and used form_open() function to create my forms. But when I submit the form, this error occurs:

相关标签:
14条回答
  • 2020-11-28 13:02

    I've found a solution to this problem which is quite simple. I removed the div with the display:none style surrounding the csrf_protection input. The div is not relevant since the input type is set to hidden. In CodeIginiterFolder/system/helpers/form_helper.php, I changed the following content (around line 75) :

    if (is_array($hidden) AND count($hidden) > 0)
    {
        $form .= sprintf("<div style=\"display:none\">%s</div>", form_hidden($hidden));
    }
    

    for the following one :

    if (is_array($hidden) AND count($hidden) > 0)
    {
        $form .= form_hidden($hidden);
    }
    
    0 讨论(0)
  • 2020-11-28 13:03

    change line no 451

    $config['csrf_protection'] = true;
    

    to

    $config['csrf_protection'] = false;
    

    Because this csrf_protection is deprecated in CodeIgniter.

    0 讨论(0)
  • 2020-11-28 13:07

    In config/config.php I have

    $config['csrf_token_name'] = 'my.token.name';
    

    But when I use var_dump for $_POST I see:

     ["my_token_name"]=> string(32) "f5d78f8c8bb1800d10af59df8c302515"
    

    CI change my csrf_token_name (sic!)

    Solution: I changed

    $config['csrf_token_name'] = 'my.token.name';
    

    to

    $config['csrf_token_name'] = 'my_token_name';
    

    Now it works.

    0 讨论(0)
  • 2020-11-28 13:08

    To everyone who tried everything that was suggested here, and still has this problem.

    My issue was the expiration time of the cookie.

    $config['csrf_expire'] = 7200;
    

    Afte the cookie expires and the user tries to submit an form, they will get the error

    The action you have requested is not allowed.
    

    I added a simple javascript to every page, which fixes the issue for 99% of your users. (the 1% being users who have JS disabled in their browser)

    setInterval(function () {
      if(alert('Your session has expired!')){}
      else    window.location.reload(); 
    }, 7200000);
    
    0 讨论(0)
  • 2020-11-28 13:09

    For those that may still be having an issue with this and for completeness I wanted to add some more information.

    I ran into this issue an although some of the answers above were helpful there are a few other things to consider when dealing with csrf.

    Starting from the top, and to make this as simple as possible.

    If your using autoload.php I typically load these. Not all are needed to correct the issue.

    Autoload.php

    $autoload['libraries'] = array('session','database','form_validation','user_agent', 'encryption');
    $autoload['helper'] = array('url', 'file', 'form');
    

    Config.php

    $config['base_url'] = 'http://somesite.org:4848/'; // Port if ur running multiple servers same machine
    $config['encryption_key'] = 'kidh743ty9fhw9afh4739hq978h'; //Get an encrypt key, make sure its set
    
    //Sessions
    $config['sess_driver'] = 'database';
    $config['sess_cookie_name'] = '_ss_session';
    $config['sess_expiration'] = 7200;
    $config['sess_save_path'] = 'Sessions';
    $config['sess_match_ip'] = FALSE;
    $config['sess_time_to_update'] = 300;
    $config['sess_regenerate_destroy'] = FALSE;
    
    // Cookies
    $config['cookie_prefix']    = '_ss_cookie';
    $config['cookie_domain']    = '.somesite.org'; // No leading slash here, cookie will not set
    $config['cookie_path']      = '/';
    $config['cookie_secure']    = FALSE;
    $config['cookie_httponly']  = FALSE;
    
    // Global XSS - This is deprecated in version 3 
    $config['global_xss_filtering'] = FALSE;
    
    // CSRF
    $config['csrf_protection'] = TRUE;
    $config['csrf_token_name'] = '_ss_csrf_token';
    $config['csrf_cookie_name'] = '_ss_csrf_name';
    $config['csrf_expire'] = 7200;
    $config['csrf_regenerate'] = TRUE;
    $config['csrf_exclude_uris'] = array();
    

    The Controller - The best method for handling csrf is to use a redirect and set flash data.

    Register.php

    <?php defined('BASEPATH') OR exit('No direct script access allowed');
    
        class Register extends CI_Controller
        {
    
          function __construct(){
            parent::__construct();
    
          }
    
          public function index(){
              $this->load->view('auth/register');
          }
    
          public function validate(){
    
            $full_name = $this->input->post('full_name');
            $email = $this->input->post('email');
            $password = $this->input->post('password');
            $password_again = $this->input->post('password_again');
            $agree = $this->input->post('agree');
    
            // do something here, then base your redirect on the response
    
            $some_model_data = $this->register_model->validate($data);              
    
            if($this->input->is_ajax_request()){
    
              // echo a json response with the token
    
              // Response array 
              // use javascript to add the new token to the form
              $response = array(
                   'data' => $some_model_data, 
                   'token'=> $this->security->get_csrf_hash();
                          );
    
              // json response 
              echo json_encode($response);  
    
            }else{
              // redirect to the page 
              $this->__validate_redirect($some_model_data);
            } 
          }
    
          private function __validate_redirect($where_to){
            switch ($where_to->redirect) {
              case 'register_page':
                redirect(base_url().'register/');
                break;
              case 'success':
                redirect(base_url().'register/success');
                break;
              default:
                redirect(base_url().'register/');
                break;
            }
    
          }
    
        }
    ?>
    

    In the view just make sure you either use:

      <?php echo form_open(); ?>
    

    This will set the csrf token or use the following inside your form in a hidden input:

      <?php echo $this->security->get_csrf_token_name(); ?>
    

    This should be all thats needed to prevent the csrf error for the most part.

    0 讨论(0)
  • 2020-11-28 13:11

    The problem solved by this Solution:

    set $config['cookie_secure'] in config file to FALSE if you're using HTTP.

    0 讨论(0)
提交回复
热议问题