Я использую CakePHP SecurityComponent
. И это очень важно, поскольку оно сохраняет формы от атак CSRF
. Мой проект состоит из 10-12 форм, и это мой первый проект CakePHP. После включения SecurityComponent
меня была небольшая проблема, но можно было избавиться после некоторых тщательных минут. Это последняя форма моего проекта, и кажется, что все правильно для меня, но форма еще черная 🙁 Может кто-нибудь, пожалуйста, сообщите мне о проблеме? Я не хочу отключать проверку CSRF или SecurityComponent
. Вот мой взгляд код:
<?php echo $this->Form->create('Record'); ?> <script type="text/javascript"> var me = new MetroExam(); </script> <div class="exam_paper"> <div class="question_box" id="q_b"> <div class="q_n_a_header"> <div class="instructions"> <b>Instructions:</b><br> <?=$inst['value_text']; ?> </div> <div id="timer">Please wait</div> </div> <div id="q_paper"> <img id="q" style="display: none;" src="/oes/<?=$exam['path'].'?ts='.time(); ?>"> <img id="loading_img" src="/oes/img/loading.gif"> </div> </div> <div class="ans_box" id="a_b"> <!-- information about answer paper. !important --> <?php $i = 0; //these fields are essential for evaluating ans paper echo $this->Form->hidden('submit', array('value' => 'true')); echo $this->Form->hidden('start_time', array('value' => '')); echo $this->Form->hidden('end_time', array('value' => '')); echo $this->Form->hidden('duration', array('value' => '')); echo $this->Form->hidden('valid', array('value' => '')); echo $this->Form->hidden('passed', array('value' => '')); //options for all radio $options = array( '1' => 'A', '2' => 'B', '3' => 'C', '4' => 'D' ); if($exam['choices'] == 5){ $options['5'] = 'None'; } $questions = (int)$exam['questions']; // 40 <= $exam['questions'] <= 100 $i = 1; while($questions--){ echo '<div class="'.(($i%2)==1?'each_answer_even':'each_answer_odd').'" id="ans-'.$i.'">'; echo '<div class="q_number">'.($i <= 9 ? '0'.$i : $i).'</div>'; $name = 'ans'.str_pad($i, 3, '0', STR_PAD_LEFT); $attributes = array('empty' => false, 'legend' => false, 'onclick' => 'me.answer_click('.$i.')'); echo '<div class="mcq">'.$this->Form->radio($name, $options, $attributes).'</div>'; echo '</div>'; $i++; } echo $this->Form->end('Submit'); ?> </div> </div>
в<?php echo $this->Form->create('Record'); ?> <script type="text/javascript"> var me = new MetroExam(); </script> <div class="exam_paper"> <div class="question_box" id="q_b"> <div class="q_n_a_header"> <div class="instructions"> <b>Instructions:</b><br> <?=$inst['value_text']; ?> </div> <div id="timer">Please wait</div> </div> <div id="q_paper"> <img id="q" style="display: none;" src="/oes/<?=$exam['path'].'?ts='.time(); ?>"> <img id="loading_img" src="/oes/img/loading.gif"> </div> </div> <div class="ans_box" id="a_b"> <!-- information about answer paper. !important --> <?php $i = 0; //these fields are essential for evaluating ans paper echo $this->Form->hidden('submit', array('value' => 'true')); echo $this->Form->hidden('start_time', array('value' => '')); echo $this->Form->hidden('end_time', array('value' => '')); echo $this->Form->hidden('duration', array('value' => '')); echo $this->Form->hidden('valid', array('value' => '')); echo $this->Form->hidden('passed', array('value' => '')); //options for all radio $options = array( '1' => 'A', '2' => 'B', '3' => 'C', '4' => 'D' ); if($exam['choices'] == 5){ $options['5'] = 'None'; } $questions = (int)$exam['questions']; // 40 <= $exam['questions'] <= 100 $i = 1; while($questions--){ echo '<div class="'.(($i%2)==1?'each_answer_even':'each_answer_odd').'" id="ans-'.$i.'">'; echo '<div class="q_number">'.($i <= 9 ? '0'.$i : $i).'</div>'; $name = 'ans'.str_pad($i, 3, '0', STR_PAD_LEFT); $attributes = array('empty' => false, 'legend' => false, 'onclick' => 'me.answer_click('.$i.')'); echo '<div class="mcq">'.$this->Form->radio($name, $options, $attributes).'</div>'; echo '</div>'; $i++; } echo $this->Form->end('Submit'); ?> </div> </div>
Это в основном форма экзамена MCQ. Там, где каждая группа имеет 4 или 5 переключателей и от 40 до 100 групп в форме. Я использую CakePHP 2.4. Заранее спасибо.
В соответствии с комментариями проблема возникает из-за изменения скрытых значений формы. Способ работы SecurityComponent состоит в том, что он «блокирует» имя полей, поэтому evildoer не может добавлять новые поля или изменять значения после отправки формы. Но он еще более строг со скрытыми значениями, поскольку он блокирует имя и значение поля. Поэтому, изменив его с помощью jQuery, вы делаете черную дыру своей собственной формой.
Там хороший маленький пост, где я узнал об этом, взгляните на него . Здесь автор объясняет два пути обхода этой проблемы. Один из них – отключить защиту для скрытых полей, поэтому хэш, рассчитанный для токена, не включает эти значения … который не очень безопасен …
И еще одно решение – изменить FormHelper и сказать «заблокировать» имена скрытых полей, но не значения. Я не помню, какую версию Cake автор использует для примера, но приведенный здесь код должен быть практически то же самое. Таким образом, с помощью этого решения вы можете сообщить, что форма не будет настолько строгой с вами с помощью массива параметров.
О, и другой вариант, данный там (это то, что я обычно использую) (я только что прочитал его сейчас … Я думал, что сам это по-моему … ну, ну, просто нужно использовать обычные текстовые поля ввода для те, которые вы хотите скрыть, и добавьте стиль css, например display:none
.
Это зависит от вас, что вы считаете лучшим. Мне нравится опция css, потому что она проще, и действительно, если кто-то собирается запутаться в моем CSS-сообщении (с помощью firebug или что-то в этом роде), они могут так же хорошо справляться со значениями скрытых полей, это не требует больше усилий. В любом случае вы должны выполнить все дополнительные шаги и проверки при обращении с этой формой. Но, как я уже сказал, до вас, как вы думаете, лучше всего подходит для вашей ситуации.
В дополнение к тому, что уже было опубликовано, вот что еще может вызвать проблему: в моем случае скрытый ввод изменил имя.
$this->Form->create('ExampleModel'): $this->Form->input('foo_bar', array( 'type' => 'hidden', 'name' => 'foo_bar', ));
В результате окончательные данные $this->request->data
имели соответствующий ключ $this->request->data['foo_bar']
. Он не был в массиве $this->request->data['ExampleModel']
, и в этом и была проблема.
Чтобы исправить эту проблему, мне пришлось удалить ключ из шаблона, чтобы входные данные принадлежали данным модели, а затем просто измените контроллер, чтобы принять это значение.
Надеюсь, это помогает кому-то другому.
Обновление : это также будет работать с формой, не привязанной к какой-либо модели, например:
$this->Form->create(false, array( 'url' => '/example', )):