如何防止用户在网站上多次发布数据
我正在开发一个 Web 应用程序 (J2EE),我想知道可用于处理来自浏览器的双重发布的选项。
我过去看到和使用的解决方案都是客户端的:
- 用户单击提交按钮后立即将其禁用。
- 遵循 POST-Redirect-GET 模式以防止用户单击后退按钮时发生 POST。
- 处理表单的 onSubmit 事件并使用 JavaScript 跟踪提交状态。
如果可能的话,我更愿意实施服务器端解决方案。 是否有比我上面提到的更好的方法,或者客户端解决方案是最好的?
I am working on a web application (J2EE) and I would like to know the options that are available for handling a double post from the browser.
The solutions that I have seen and used in the past are all client-side:
- Disable the submit button as soon as the user clicks it.
- Follow a POST-Redirect-GET pattern to prevent POSTs when the user clicks the back button.
- Handle the onSubmit event of the form and keep track of the submission status with JavaScript.
I would prefer to implement a server side solution if possible. Are there any better approaches than the ones I have mentioned above, or are client-side solutions best?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
实现一个 uniqueid 来配合请求并将其与执行一起记录。 如果该 ID 已被记录,则您无需再次执行该作业。 这有点像后备解决方案 - 您应该尝试禁用按钮或链接客户端以及您自己的建议
Implement a uniqueid to go with the request and log it along with the execution. If the id was already logged, you don't do the job again. This is kinda like the fallback solution - you should try and disable the button or link clientside as well as you suggested yourself
如果您碰巧使用 Struts,它内置了类似的东西。
http://struts.apache.org/ 1.x/apidocs/org/apache/struts/util/TokenProcessor.html
Struts has something like this built in if you happen to be using it.
http://struts.apache.org/1.x/apidocs/org/apache/struts/util/TokenProcessor.html
您可以提供一个“票”作为表单的一部分,一些随机数 - 并确保它不会在服务器端被接受两次。
You could supply a "ticket" as part of the form, some random number - and make sure it doesn't get accepted twice, on the server side.
我想到了两种服务器端解决方案:
Two server-side solutions come to mind:
我们使用时间敏感的一次性票。 它就像某种会话 ID。 但它与表单/页面相关。
当用户提交页面时,您将丢弃票证,并且仅处理带有有效票证的页面。 同时,您可以通过将票证附加到用户来加强安全性,因此,如果票证是由非票证提交对象的用户提交的,您将拒绝该请求。
we use a time sensitive, one time ticket. It's like a session id of sort. But it is tied to the form/page.
You discard the ticket when the user submits the page, and you only process pages that comes with a valid ticket. You can, at the same time, tighten security by attaching the ticket to a user, so tat if a ticket comes in that is submitted by a user that is not the user that the ticket was submitted to, you reject the request.
很难实施一个防白痴的解决方案(因为他们总是在改进白痴)。 无论您做什么,客户端都可能被操纵或执行不正确。
您的解决方案必须是服务器端才能可靠且安全。 > 也就是说,一种方法是检查请求并检查系统/数据库状态或日志以确定它是否已被处理。 理想情况下,如果可能的话,服务器端的进程应该是幂等的,如果不能的话,它必须防止重复提交。
Its hard to implement an idiot-proof solution (as they are alway improving the idiots). No matter what you do, the client side can be manipulated or perform incorrectly.
Your solution has got to be server side to be reliable and secure. That said, one approach is to review the request and check system/database state or logs to determine if it was already processed. Ideally, the process on the server side should be idempotent if possible, and it will have to protect against dupe submits if it can't be.
我会使用时间戳并将值与您的服务器端代码进行比较。 如果两个时间戳足够接近并且具有相同的 IP 地址,则忽略第二个表单提交。
I'd use a timestamp and compare values with your server side code. If two timestamps are close enough and have the same IP address, ignore the second form submission.