2

When working in PHP, to avoid duplicate form submissions, I used to generate a unique id of some sort, store it into a session variable, and have the id in the form, so on submission I can compare the values, regenerating the session value at that point. I never considered it a great solution, but I was never able to think of/find a better solution.

Now, I'm doing an Angular front end with a PHP backend (Lumen), and I'm struggling to think of a solution that doesn't involve me writing into a database. Unless I'm misunderstanding something, I can't use sessions between Angular and PHP, right? So this solution won't work. The only other thing I can think of is to have a key/pair value in a DB, but I never quite understood how that prevents duplicates on something like an accidental double click, wherein the session/database may not update it's key before the second submission starts processing. And as I'm learning more about stateless systems, it feels like a session isn't the best place to put this sort of thing?

Overall, I'm having trouble with creating a secure, backend system to avoid duplicate forms. With angular, I can always prevent duplicate submissions through preventing the button from being clicked, the API call from firing, etc, but I'd like to add backend protection too, and I'd love to hear how the experts do it.

Rohit
  • 3,018
  • 2
  • 29
  • 58
  • 2
    why would you need backend protection to prevent duplicate form submissions? is there something safety-critical going on? To me, it doesn't seem like a thing one should really care about beyond simple client-side check. – eis Jul 11 '17 at 19:55
  • 1
    IMHO I think it's a client side matter, Why not just disabling the button after it gets clicked – Accountant م Jul 11 '17 at 20:01
  • Both these and the answers below kind of answered my question: my mentality has always been, don't trust the front end. But in this case, the front end/back end shouldn't care what each other is doing. Thanks. – Rohit Jul 11 '17 at 20:04
  • @RhoVisions Yup, that is exactly it. The back end and front-end don't care what the other is doing, and they shouldn't have to. Among other things, this lets one back-end serve a variety of front-end clients. Right now you have a web app (angular). Later you may add on mobile apps: ionic, swift, java, whatever. Either way, those clients can interact with your back-end APIs in the exact same way, and since your back end doesn't care what the front-end is doing (or even who it is), adding in additional clients is very easy. – Conor Mancone Jul 11 '17 at 20:08
  • @RhoVisions you are welcome. yes, you are right, you should never trust the client , but "duplicate form submissions" is not considered an intended malicious action from the client, it is just an action happens by accident, -like clicking the button twice - and even more it might be something intended by the client to submit the same data more than once. what you really should care about at your back end is things like flooding requests and bots. – Accountant م Jul 11 '17 at 20:23

3 Answers3

2

In most cases this should be protected in the front end. Backend protection solution depends upon your definition of unique request. You can create a composite key from the attributes that together makes the request unique. For eg. email id, request id, or any set of request parameters

DB will not accept duplicate keys and you can catch the exception and gracefully handle it on front end.

Eg. Newsletter subscription request application - the uniqueness of the request is determined by email address and newsletter type

1

I'm sure there are ways to hack it, but I think the short answer is that you don't want to hack it. When you transition to a split back/front end, one thing you are doing is specifically making your API calls stateless. This is a good thing! The statelessness, lack of sessions, etc, can dramatically simplify your back-end application. In short, statelessness is half the reason why you do something like this.

Preventing double submits as you are used to doing is decidedly something that you need a stateful application to do. As a result, it is now the job of the front-end application exclusively.

Your best bet is to think about your application in a whole new way. Your PHP backend handles stateless REST requests, and as such it is not PHP's problem if it gets duplicate submissions. In practice angular should have no problem making sure duplicates don't get submitted (it is really easy to prevent it on the front-end). Your PHP backend does need to make sure it always returns appropriate responses. So for instance on a registration page, back-to-back duplicate registration requests would result a successful registration followed by a failed registration with a message of "That email already exists" (or something like that). Otherwise, your PHP backend doesn't care. I can still do its job. It's the client's job to make sure the double submit doesn't happen, or make sense of the conflicting answers if it does.

Statelessness is a desirable quality in API calls: you'll make your life much more difficult if you muck that up.

Conor Mancone
  • 1,940
  • 16
  • 22
0

The logic is simple, just disable the submit button and show a loader to the user on form submit and enable the button again and hide the loader when you get a response from the first API and also you can empty the form fields too. Now, If the user submits the form again with same details you can easily access the old saved data and compare them and can warn the user that fields are already submitted.

If you are using Angular 4 or 2,

[disabled] , *ngIf or [hidden], Observables will help

to reset form formRef.reset() https://codecraft.tv/courses/angular/forms/submitting-and-resetting/

and angular 1 ng-disabled, ng-if and HTTP promise will help and for resetting form angularjs form reset error

vaibhavmaster
  • 659
  • 6
  • 10