What is the best way to prevent duplicate post/get/patch/delete request

If a user accidentally presses submit button twice, the requested method will be performed twice.

If someone is adding the product record and accidentally presses submit button twice or presses enter button twice, the multiple records will be stored in the database.

The same happens for GET, PATCH and DELETE requests.

Currently applying the below logic:
In the controller declare one random generated string in the unique session identifier and pass the same string as a variable in the view.

Set the variable in the form post field and send it back as the post field in the controller.

  • What is the best way to prevent duplicate submissions?
  • Can we prevent using CSRF tags?
  • How to renew CSRF tag instantly after validation?
public AbcController Extends Controller
{
    public actionCall()
    {
        if(Yii::$app->request->post())        
        {
             if(Yii::$app->request->post('variable') == Yii::$app->session->get('lm_product_unique')
             {
                Yii::$app->session->delete('lm_product_unique'); // delete the session to avoid duplicate entry
                // Proceed request
             }
        }

        $variable = Yii::$app->security->generateRandomString();
        Yii::$app->session->set('lm_product_unique', $variable);
        echo $this->render('viewfile',['variable'] => $variable);
    }
}
1 Like

Disable the submit button programmatically after click and enable after request completed according to response.

1 Like

Excellent and reliable at some point.

But server-side code is more secure. So is there any way to do it?

  1. Add transaction UUID to the form/client request.
  2. Save it at the server side when operation is complete.
  3. At the start of the operation check if operation with such UUID isn’t there.
4 Likes

This sounds interesting…I suppose it could work for checking duplicate API calls and data imports as well if that were an issue?

Kindly describe a bit further how you are handling/storing this in the model and database.
I am assuming you have a model attribute hence a DB column for this UUID (hidden) field value that also has a unique validation rule check on it?

1 Like

Yes, that would work for duplicate anything.

You are correct about how it is stored and checked.

3 Likes

You should also check this UUID right before commit your transaction.
In some rare cases your API can start second transaction from same user before previous one was committed.