Я хочу создать фильтр для моих действий по добавлению, обновлению и удалению в моих контроллерах, чтобы автоматически проверять,
- были вызваны в POST, в отличие от GET или какого-либо другого метода
- and have the pageInstanceIDs which I set in the forms on my views
- protects against xss
- protects against double submission of a form
- from submit button double click
- от кнопки «Назад», нажатой после отправки
- с сохраненного или добавленного в закладки URL-адреса
В настоящее время я расширил \lithium\action\Controller с помощью AppController, и там определены мои действия добавления, обновления и удаления. У меня также есть логическая функция в моем AppController, которая проверяет, находятся ли соответствующие идентификаторы pageInstanceID в сеансе или нет.
Ниже мой код:
public function isNotPostBack() {
// pull in the session
$pageInstanceIDs = Session::read('pageInstanceIDs');
$pageInstanceID = uniqid('', true);
$this->set(compact('pageInstanceID'));
$pageInstanceIDs[] = $pageInstanceID;
Session::write('pageInstanceIDs', $pageInstanceIDs);
// checks if this is a save operation
if ($this->request->data){
$pageInstanceIDs = Session::read('pageInstanceIDs');
$pageIDIndex = array_search($this->request->data['pageInstanceID'], $pageInstanceIDs);
if ($pageIDIndex !== false) {
// remove the key
unset($pageInstanceIDs[$pageIDIndex]);
Session::write('pageInstanceIDs', $pageInstanceIDs);
return true;
}
else
return false;
} else {
return true;
}
}
public function add() {
if (!$this->request->is('post') && exist($this->request->data())) {
$msg = "Add can only be called with http:post.";
throw new DispatchException($msg);
}
}
Затем в своих контроллерах я наследую от AppController и реализую действие следующим образом:
public function add() {
parent::add();
if (parent::isNotPostBack()){
//do work
}
return $this->render(array('layout' => false));
}
что гарантирует, что форма использовала POST и не была отправлена дважды (кнопка "Назад" или щелчок по довольным пользователям). Это также помогает защититься от XSS.
Я знаю, что для этого есть плагин, но я хочу реализовать его как фильтр, чтобы мои методы контроллера были чище. Реализованный таким образом, единственным кодом в моих действиях является часть //do work и оператор return.