5

I'm currently working on a project which requires that we integration a 3rd party SOAP API to handle a number of basic CRUD type operations.

Our current implementation allows us to leveraging the Laravel framework's form validation classes prior to execution of these API requests data; however I have some concerns since we're not leveraging any type of queuing mechanism.

The current solutions stack involves placing a heavy burden on the NGINX web server to spawn additional workers for each blocking user request. Obviously, this may lead to some issues down the line in terms of scalability.

There's also the possibility that users will frequently "refresh" pages after submitting form request data.

I've been looking into the Post/Redirect/Get pattern as a possible solution however I'm not quite sure that I completely understand the concept.

Here's a quote from one stackoverflow discussion:

  1. The client gets a page with a form.

  2. The form POSTs to the server.

  3. The server performs the action, and then redirects to another page.

  4. The client follows the redirect.

As stated above, these are long API calls and step 3 may take upwards of 10s to complete execution- what's to prevent the user from continually refreshing the page after step 2?

  • I think your step 3 "action" need to start background process only (pass post data further) and immediately redirect to waiting for result loop (or any other page - result should be saved by background process anyway). This way refreshing page won't restart processing. – shudder Jul 6 '15 at 9:48
3

I have answered this question on StackOverflow as well - I place my answer here for easy reference...

The PRG pattern alone will not prevent this, as the P action in it takes time (which is usually the case) and the user can submit the form again (via click or browser refresh), which will cause the PRG pattern to "fail".

Note that malicious users can also bypass all of your client side measures by running multiple http posts in quick succession.

A solution to all of the above is to check for duplicate submissions on server side against your anti-forgery token.

If you make use of a hidden anti-forgery token in your form (as you should), you can cache the anti-forgery token on first submit and remove the token from cache if required, or expire the cached entry after set amount of time.

You will then be able to check with each request against the cache whether the specific form has been submitted and reject it if it has.

1

I think as per the PRG pattern if there is a refresh after step2 there won't be an issue as the client(browser) will receive and use the redirect url.

The problem happens when the user refreshes before step 2 is completed(before sending the redirect url)!

  • So...it sounds like the PRG pattern will not help me in this case. Is that correct? – user2308097 Jul 6 '15 at 1:28
  • 1
    We may not say that. Rarely it may fail to resolve our purpose. In addition to this you can have form based token approach. – Ratha Jul 6 '15 at 2:12
  • 1
    You're referring to CSRF tokens? I suppose that's one way of doing it. – user2308097 Jul 6 '15 at 4:43
0

The server solution with unique tokens is most robust, but not so user friendly. It's not a great user experience to wait for a page to load and receive errors on reload.

On client side you could redesign to use XHR requests with UI hints that data is processing and rejecting any submits/requests, before the response is received.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.