我想为我的控制器中的添加、更新和删除操作创建一个过滤器,以自动检查它们是否
- 在 POST 中调用,而不是 GET 或其他方法
- 并拥有我在视图中的表单中设置的 pageInstanceID
- 防止 xss
- 防止重复提交表单
- 从提交按钮双击
- 提交后按下后退按钮
- 来自正在保存或添加书签的 url
目前,我使用 AppController 扩展了 \lithium\action\Controller,并在其中定义了我的添加、更新和删除操作。我的 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 语句。