5

我发现 CakePHP 中的安全组件通过将标记作为隐藏值添加到表单来帮助防止 CSRF。

我想知道是否有任何方法可以防止使用此组件或其他一些组件/帮助程序提交重复的表单?

在以前的项目中,我使用了保存在会话中的唯一哈希,在提交时读取然后删除。重复提交将具有相同的哈希值并且会产生错误。

谢谢

4

7 回答 7

4

我已经放置了禁用按钮的 onClick 事件,如下所示:

<?= $this->Form->button('Salvar', [
                    'value' =>'Submit', 
                    'onClick' => 'form.submit();this.disabled=true'
]) 
?>
于 2016-04-07T19:03:21.220 回答
2

您可以在 Cake 中实现与以前相同类型的东西。

在提交时,设置一个会话变量,将该表单标记为已提交。确保在它之后加上到期时间(几秒钟内就可以了)。如果在您处理表单时会话变量存在(并且您在过期时间内),那么您需要重新提交,所以不要保存表单数据。

我建议在模型的 save(..) 方法中执行此操作,因此您不必担心将其添加到多个代码位置。

于 2009-03-16T22:45:33.113 回答
2

CakePHP 2.x 中的安全组件有一个特性,允许您选择使用相同的安全令牌直到它过期或只使用一次。把它放在你的控制器 beforeFilter 方法中:

$this->Security->csrfUseOnce = true;

在此处查找更多信息

于 2012-04-06T13:35:13.143 回答
2

@DoctorFox 已经回答了这个问题csrfUseOnce = true,但这会让你陷入你仍然必须管理的黑洞。所以对我来说完整的解决方案是:

class YourAppController extends AppController {

    public $helpers = array('Html', 'Form');
    public $components = array('Security');

    public function beforeFilter() {
        $this->Security->csrfUseOnce = true;
        $this->Security->blackHoleCallback = 'blackhole';
    } 

    public function blackhole($type) {
        $this->redirect(array('action' => 'index'));
    }

如果没有重定向,您仍然可以提交双重表单。

参考:CakePHP 安全组件

于 2014-07-14T22:32:24.957 回答
1

就做PRG Pattern ..很简单吧?!好吧,至少每个人都是这么说的,但没有人给出明确的答案!我花了一周的时间搜索和挖掘,然后“新手”决定自己做点什么!这是在 cakephp 中执行此操作的一种方法(我使用 2.0.5):

无论代码如何,这里的逻辑步骤都是:
1- 设置数据
2- 验证(还不要创建())
3- 将 $this->request->data 写入会话变量
4- 重定向到 saveData 操作

内部 saveData 操作:
5- 读取并保存会话变量
6- 删除会话变量
7- create()
8- 将数据保存到模型
9- 重定向

这是您的代码可能看起来如何的示例。
**收件人:“ ourController ”和“ ourModel

public function add() {
        if ($this->request->is('post')) {
            if (isset($this->request->data)) {
                $this->ourModel->set($this->request->data);
                if ($this->ourModel->validates()) {
                    $this->Session->write('myData', $this->request->data);
                    $this->redirect(array('controller' => 'ourController', 
                                           'action' => 'saveData',
                                           'ourModel' //optional but recommended
                                          )
                                    );
                } else {
                    $this->Session->setFlash('ourModel could not be saved.');
                     }
          }
.....//the rest of add() function
}

然后,您应该(在验证时)被重定向到此函数,该函数再次将您重定向到索引操作或您的逻辑将您带到的任何地方!

public function saveData($model) {
        $myData = $this->Session->read('myData');
        $this->Session->delete('myData'); //extremely important
        $this->$model->create();
        if ($this->$model->save($myData)) 
               // or $myData[$model] if you are dealing with multiple models
              {
              $this->Session->setFlash(__($model.' have been saved successfully'));
              $this->redirect(array('controller' => 'ourController',
                                    'action' => 'index'
                                    )
                               );
            } 
        } else{
            $this->Session->setFlash(__($model.' could not be saved'));
        }
        }
    }

一个简单的自我重定向可能会起作用,但在大多数情况下,您希望重定向到不同的视图(例如,到另一个表单或索引视图)

我希望这种详细说明有助于节省其他人的时间,这样就不必浪费整整一周的时间(就像我的情况一样)只是为了在服务器端执行这样的功能!

于 2013-08-15T22:27:58.817 回答
0

不了解 cake,但尽量不在 POST 请求中显示内容,进行自我重定向。双重职位将得到解决。

于 2009-03-16T22:28:59.113 回答
0

安全组件应该可以工作,此外,您还可以在发布后取消设置数据:

unset($this->data['yourModel']);
于 2012-02-10T02:05:35.477 回答