Main Purpose
- preventing new/existing user sign up with email or username that already exist in the system
Obstacle
- for every each of a keystroke, ajax will send a data to the server and will be checked if the value existed in the database.
- along with the keystroke data send by the ajax, there is also the CSRF(Cross Site Request Forgery) data
- CSRF will make sure that the request comes from the same domain where the server is, not from the outside. Otherwise we will have big trouble of security.
- so CSRF data need to be update with each of the keystroke so the form can be submitted with the updated CSRF.
- without it, the server will reject the request from the submission due to expiry of CSRF.
Solution
- update CSRF value with each of the keystroke using Ajax Success which will read the CSRF from the JQuery Cookie and "paste" it to hidden input.
- CI configuration
application/config/config.php
<?php
$config['csrf_regenerate'] = TRUE;
?>
- Back End (controller to handle the response)
application/controller/SomeController.php
<?php
public function remote_user()
{
$valid = TRUE;
$users1 = $this->account->GetAll();
$users = array();
foreach($users1->result() as $wer) {
$users[$wer->c_id] = $wer->c_headerb;
}
if (NULL !== $this->input->post('username') && array_key_exists($this->input->post('username'), $users)) {
$valid = FALSE;
} else if (NULL !== $this->input->post('email')) {
$email = $this->input->post('email');
foreach ($users as $k => $v) {
if ($email == $v) {
$valid = FALSE;
break;
}
}
}
echo json_encode(array('valid' => $valid,));
}
?>
- Front End (view for handling the request)
application/views/register.php
<html>
<?=form_open('', array('class' => 'mbr-form', 'autocomplete' => 'off', 'id' => 'productForm'))?>
<div class="form-group row">
<?=form_label('Email : ', 'pass3', array('class' => 'col-sm-2 col-form-label mbr-fonts-style display-7')) ?>
<div class="col-sm-10"> <?=form_input(array('name' => 'email', 'value' => set_value('email'), 'class' => 'form-control', 'id' => 'pass3', 'placeholder' => 'Email'))?>
<br />
<?=form_error('email')?>
</div>
</div>
<?=form_close() ?>
</html>
- JQuery/Javascript (Ajax Request and Response)
application/views/register.php
remote: {
type: 'POST',
url: 'remote_user',
message: 'Please use another email ',
data: function(validator) {
return {<?=$this->security->get_csrf_token_name()?>: $.cookie("<?=$this->config->item('cookie_prefix').$this->config->item('csrf_cookie_name')?>")};
},
delay: 1, // wait 0.001 seconds
onSuccess: function(e, data) {
//hidden input csrf must be refresh, otherwise submit data wont go through the process
$('input[name="<?=$this->security->get_csrf_token_name()?>"]').val($.cookie("<?=$this->config->item('cookie_prefix').$this->config->item('csrf_cookie_name')?>"));
},
}