dongyun3335
dongyun3335
2017-07-11 19:50
浏览 60
已采纳

防止无状态系统中的重复表单提交

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.

图片转代码服务由CSDN问答提供 功能建议

在PHP中工作时,为了避免重复的表单提交,我曾经生成某种类型的唯一ID,存储它 到一个会话变量,并在表单中有id,所以在提交时我可以比较值,在那时重新生成会话值。 我从来没有认为它是一个很好的解决方案,但我从来没有想过/找到更好的解决方案。

现在,我正在使用PHP后端(流明)进行Angular前端 ,我正在努力想到一个不涉及我写入数据库的解决方案。 除非我误解了什么,否则我不能在Angular和PHP之间使用会话,对吧? 所以这个解决方案不起作用。 我能想到的唯一另一件事就是在数据库中有一个键/对值,但是我从来没有完全理解如何防止像意外双击之类的重复,其中会话/数据库可能不会在第二个之前更新它的键 提交开始处理。 当我正在学习更多关于无状态系统时,感觉就像会话不是放置这类东西的最佳位置吗?

总的来说,我在创建一个 安全的后端系统,以避免重复的表单。 使用angular,我总是可以通过阻止点击按钮,激活API调用等来防止重复提交,但我也想添加后端保护,我很想听听专家是如何做到的。< / p>

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • doushan2811
    doushan2811 2017-07-11 20:02
    已采纳

    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.

    点赞 评论
  • du21064
    du21064 2017-07-11 19:57

    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

    点赞 评论
  • dongluan2612
    dongluan2612 2017-07-11 20:10

    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

    点赞 评论

相关推荐