我想为 Controller 中的添加、更新和删除操作创建一个过滤器,以自动检查它们是否有效
- 在 POST 中调用,而不是 GET 或其他方法
- 并拥有我在 View 表单中设置的 pageInstanceID
- 防止 XSS
- 防止重复提交表单
- 从提交按钮双击
- 提交后按下后退按钮
- 来自正在保存或添加书签的网址
目前,我使用 AppController 扩展了\lithium\action\Controller 并在其中定义了添加、更新和删除操作。 我的 AppController 中还有一个 bool 函数,用于检查相应的 pageInstanceID 是否处于 session 中。
下面是我的代码:
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);
}
}
然后在我的 Controller 中,我继承自 AppController 并实现如下操作:
public function add() {
parent::add();
if (parent::isNotPostBack()){
//do work
}
return $this->render(array('layout' => false));
}
这将确保表单使用 POST 并且不会重复提交(后退按钮或单击快乐用户)。这也有助于防止 XSS。
我知道有一个插件可以实现此目的,但我想将其实现为过滤器,以便我的 Controller 方法更干净。通过这种方式实现,我的操作中的唯一代码是//do work 部分和 return 语句。
最佳答案
您可能应该从 lithium\action\Dispatcher::run()
上的过滤器开始,这里有一些伪代码。如果没有看到您的 parent::isNotPostBack()
方法,无法提供太多帮助,但这应该会让您走上正确的道路。
<?php
use lithium\action\Dispatcher;
Dispatcher::applyFilter('run', function($self, $params, $chain) {
$request = $params['request'];
// Request method is in $request->method
// Post data is in $request->data
if($not_your_conditions) {
return new Response(); // set up your custom response
}
return $chain->next($self, $params, $chain); // to continue on the path of execution
});
关于php - Controller 中的过滤方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9797633/