How to prevent duplicate / duplicate forms in CakePHP?

I found that the security component in CakePHP helps prevent CSRF by adding tokens as hidden values ​​to forms.

What was interesting to me was if it were still necessary to prevent duplication of forms using this component or some other component / helper?

In previous projects, I used a unique hash stored in the session, which is then read after sending. Resubmission will have the same hash and an error will be generated.

thanks

+4
source share
7 answers

You can implement the same type of thing in Cake as you did before.

In the view, set a session variable that marks this form as submitted. Make sure that it expires after it (a trick should be done within a few seconds). If a session variable exists when you process the form (and you are within this validity period), then you have resubmitted, so do not save the form data.

I would recommend doing this in the save (..) method of your model, so you don’t have to worry about adding it in several places in the code.

+2
source

The CakePHP 2.x security component has a feature that allows you to use either the same security token to which it expires, or only once. Put this in your beforeFilter controllers:

$this->Security->csrfUseOnce = true; 

Find more information here.

+2
source

@DoctorFox already answered it with csrfUseOnce = true , but that will throw you into black holes that you still have to manage. So the complete solution for me:

 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')); } 

If there is no call forwarding, you are still open to submit as a double form.

Link: CakePHP Security Component

+2
source

Just make a PRG template .. Is it really that simple? Well, at least what everyone says, but no one gives a clear answer! It took me a week to search and dig, and then Novice decided to do something on my own! Here is one way to do this in cakephp (I am using 2.0.5):

Regardless of the code, there is logic in the steps:
1- given data
2- confirm (do not create yet ())
3- write $ this-> request-> data to the session variable
4- redirect to saveData action p>

Inside saveData action:
5- read and save the session variable
6 - DELETE session variable
7-create ()
8 - saving data in the model
9-redirection

Here is an example of what your code might look like.
** Attn: " our control " and 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 } 

Then you should redirect (when checking) to this function, which redirects you again to the indexing action or wherever your logic takes you!

 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')); } } } 

A simple self-redirect may work, but in most cases you want to redirect to a different view (for example, to a different form or to an index view).

I hope that this development will save time on others, so you do not need to spend a whole week (as in my case) to make such functionality on the server side!

+1
source

I have included the onClick event, which disables this button:

 <?= $this->Form->button('Salvar', [ 'value' =>'Submit', 'onClick' => 'form.submit();this.disabled=true' ]) ?> 
+1
source

I don’t know about the cake, but try not to display the content in the POST request, do your own redirection. Double mail will be resolved.

0
source

The Security component should work, in addition, you can also disable data immediately after publication:

 unset($this->data['yourModel']); 
0
source

All Articles