0

How can I prevent multiple submissions when a submit button is hit very fast?

This is my store function:

public function store()
{
    $input = Input::except('_token');
    $country = new Country($input);

    $country->save();
}

I thought about adding validation for unique ids. But I thought that if the same method is executed several times each Country instance will be different, hence will have different ids, so the entry will be created anyway. I don't like the idea of using validation for this situation anyway.

I have something around that prevents multiple submissions when updating an entity:

public function updatePost(Post $post) {
    if (count($post->getDirty()) > 0) {
        $post->save();
        return Redirect::back()->with('success', 'Post is updated!');
    } else {
        return Redirect::back()->with('success', 'Nothing to update!');
    }
}

However, getDirty() wouldn't be of any help when storing a new entity.

I have been searching for a while and I didn't find anything straight forward.

What is the usual way to deal with this issue?

edit. tried using Redirect::route() but I got the same results.

Community
  • 1
  • 1
dabadaba
  • 9,064
  • 21
  • 85
  • 155
  • Duplicate of http://stackoverflow.com/questions/17239586/laravel-4-prevent-multiple-form-submissions-csrf-token ? – Unnawut Jul 26 '14 at 19:33
  • I saw that and it doesn't help. – dabadaba Jul 26 '14 at 19:33
  • There's a comment on the answer that says the options in the answer are not options. Both `Session::put('_token', sha1(microtime()))` and `Redirect::route('form/success')->with("data", $myData)` need to be done. And you need to do `Session::put('_token', sha1(microtime()))` at the beginning of `store()` by the way. – Unnawut Jul 26 '14 at 19:36
  • 1
    Why can't you use the approach from the other stackoverflow? Save the IP/time of entry of the database. If another entry within a predefined time is requested by the same IP, reject it – Kousha Jul 26 '14 at 23:08

2 Answers2

0

I think there is a combinations of approaches you could/should consider here.

First, I would definitely say that a model rule enforcing uniqueness could be applied to protect you app's data integrity.

Second, to prevent this from happening in the first place, you may want to look at a implementing a simple Javascript function that disables the Submit button once clicked.

mass6
  • 96
  • 6
  • relying on JavaScript for this kind of thing is a terrible idea because the user could disable it and the problem would persist – dabadaba Jul 26 '14 at 21:01
0

Here is my approach:

public function store()
{
    $input = Input::except('_token');
    $host = gethostname();

    // Using -1 for $last_update will always ensure that the next line is true if no
    //   entry exists
    $last_update = Session::has($host) ? Session::get($host) : -1;

    // If no entry exists (-1), then the below statement will always be true!
    $allow_entry = (microtime() - $last_update) > $SOME_TIME;

    if ($allow_entry)
    {
        $country = new Country($input);
        $country->save(); 

        // Only update the Session if an entry was inserted
        Session::put($host) = microtime();
    }  
}

Basically, you use a Session with the key being the hostname of the user. And the value being the time of entry.

Kousha
  • 32,871
  • 51
  • 172
  • 296