2016-12-30 2 views
1

Привет, Я ищу процесс регенерации токена csrf в codeigniter, когда когда-либо форма отправляется с использованием ajax. Я хочу, чтобы токен восстанавливался без обновления страницы. Есть ли способ сделать это.Regenerate CRSF token codeigniter on submit Ajax

ответ

2

Существует два решения, которые я использую в разное время в зависимости от ситуации.

1. Слегка грязный способ, но рекомендуется

Получить имя лексемы и значение хэш-функции в контроллере и установить его где-нибудь на вашей странице в поле данных (там, где вы выбираете). Например

// get the data and pass it to your view 
$token_name = $this->security->get_csrf_token_name(); 
$token_hash = $this->security->get_csrf_hash(); 

// in your view file, load it into a div for instance 
<div id="my_div" data-token="<?php echo $token_name; ?>" data-hash="<?php echo $token_name; ?>" 

Теперь в вашем JS код Ajax, вы можете просто прочитать значения данных в «my_div», чтобы получить правильные данные для вашего AJAX вызова.

Это делается намного проще, если у вас есть подлинная форма на вашей странице, и в этом случае вместо использования какого-либо div просто не используйте form_open в форме, а создайте поле скрытой формы самостоятельно, чтобы вы могли читать это легко через js.

<input type="hidden" id="my_data" name="<?=$csrf['name'];?>" value="<?=$csrf['hash'];?>" /> 

Это важная бито: Конечно, после отправки почтовых данных, вам необходимо обновить значение маркеров хэша (в вашем поле ввода формы или данных сНа, однако вы решили сделать это). Напишите функцию js, называемую refresh_csrf_data, и используйте «GET», чтобы получить данные и обновить поля. Затем эту функцию можно вызывать всякий раз, когда вы делаете сообщение ajax.

Таким образом, каждый вызов ajax считывает данные маркера, выполняет вызов, а затем обновляет данные токена, готовые для следующего вызова.

2. Легко, но менее безопасный

В качестве альтернативы, вы можете отключить CSRF для AJAX звонки с помощью

в файле конфигурации для настройки CSRF.

3. Еще проще, но и менее безопасным, и я не использую его Наконец, вы можете отключить регенерирующим CSRF хэш на каждом представлении

$config['csrf_regenerate'] = FALSE; 

Но делать это с осторожностью. Это может открыть вам определенные типы атак.

Ответ, который лучше всего подходит для вас, целиком и полностью зависит от типа страницы, использования, если пользователи регистрируются в то время или нет, это критически важные вещи или незначительные вещи, это финансовый и т.д.

Ничто не является полностью безопасным, поэтому иногда это компромисс. Лично я бы сделал это с CSRF на полном восстановлении, без исключений в URI, и перезагружать данные маркера и хеша всякий раз, когда мне нужно. Это кажется сложным, и это нужно объяснить, но как только вы это сделали один раз, это действительно легко сделать снова и снова, когда вам это нужно, и ваш сайт будет намного безопаснее, чем просто избежать проблемы с другими вариантами.

0

Я считаю, с помощью функции form helper лучше работает с Codeigniter CSRF и прекращает метания ошибки CSRF Если вы используете обычный HTML вход будет продолжать бросать ошибку CSRF.

Вот пример АЯКС

<?php echo form_open('controller/example', array('id' => 'form-login'));?> 
<?php 

$username_array = array(
'name' => 'username', 
'id' => 'username', 
'class' => '' 
); 

echo form_input($username_array); 

?> 

<?php 

$password_array = array(
'name' => 'password', 
'id' => 'password', 
'class' => '' 
); 

echo form_password($password_array); 

?> 

<?php 

$submit_array = array(
'name' => 'submit', 
'id' => 'submit', 
'class' => '', 
'value' => 'Submit', 
'type' => 'submit' 
); 

echo form_input($submit_array); 

?> 

<?php echo form_close();?> 

<script type="text/javascript"> 
$('#submit').click(function(e){ 

     e.preventDefault(); 

     var post_data = { 
      'username' : $('#username').val(), 
      'password' : $('#password').val(), 
      '<?php echo $token_name; ?>' : '<?php echo $token_hash; ?>' 
     }; 

     $.ajax 
     ({ 
      type: 'post', 
      url: "<?php echo base_url('example/');?>", 
      data: post_data, 
      dataType: 'json', 
      success: function(response) 
      { 
       if (response['success'] == true) { 

        // Success 

       } else { 

        // Error 

       } 

      } 
     }); 
}); 
</script> 

Пример

public function index() { 
    $data['token_name'] = $this->security->get_csrf_token_name(); 
    $data['token_hash'] = $this->security->get_csrf_hash(); 

    $this->load->view('login_view', $data); 
} 

public function example() { 
    $data = array('success' => false, 'messages' => array()); 

    $this->form_validation->set_rules('username', 'username', 'required'); 
    $this->form_validation->set_rules('password', 'password', 'required'); 

    if ($this->form_validation->run() == false) { 

     foreach ($_POST as $key => $value) { 
      $data['messages'][$key] = form_error($key); 
     } 

    } else { 


     $data['success'] = true; 
    } 

    echo json_encode($data); 
} 
+0

Это хорошо для один раз кусок JS, но не для AJAX , При следующем вызове функции токены будут недействительными. Также не работает, если js находится в файле .js, а не закодирован в контроллере или в представлении. – PaulD

0

, если это не на сессии, то вы контроллер будет как этот

public function save_date() // or whatever function you like 
{ 
$regen_token = $this->security->get_csrf_hash(); 
$data = array(
     "data" => $this->input->post('datas'), 
); 
$insert = $this->w_m->save($data); 
echo json_encode(array("regen_token" => $regen_token)); 
} 

в вашем AJAX будет выглядеть следующим образом:

$.ajax({ 
url: "your url", 
type: "POST", 
data: { your data }, 
dataType: "JSON", 
success: function(data) 
{ 
    $("name or id of your csrf").val(JSON.stringify(data.regen_token)).trigger("change"); // this will be the function that every post you'll request and it automatically change the value of your csrf without refreshing the page. 
}, 
error: function(errorThrown) 
{ 
    console.log(errorThrown); 
} 
}); 
Смежные вопросы