如何防止用户在网站上多次发布数据

时间:2008-09-24 22:33:14

标签: java-ee double-submit-problem

我正在开发一个Web应用程序(J2EE),我想知道可以从浏览器处理双重帖子的选项。

我过去看过和使用的解决方案都是客户端的:

  • 用户点击后立即停用提交按钮。
  • 按照POST-Redirect-GET模式阻止用户单击后退按钮时的POST。
  • 处理表单的onSubmit事件,并使用JavaScript跟踪提交状态。

如果可能的话,我更愿意实施服务器端解决方案。有没有比我上面提到的更好的方法,或者最好是客户端解决方案?

7 个答案:

答案 0 :(得分:8)

您可以在表单中提供“票证”,一些随机数 - 并确保它在服务器端不会被接受两次。

答案 1 :(得分:8)

很难实施一个防止白痴的解决方案(因为他们总是改善白痴)。 无论您做什么,客户端都可能被操纵或执行不正确。

您的解决方案必须是服务器端才能可靠和安全。也就是说,一种方法是检查请求并检查系统/数据库状态或日志以确定它是否已经处理。理想情况下,服务器端的进程在可能的情况下应该是幂等的,如果不能,则必须防止欺骗提交。

答案 2 :(得分:3)

我想到了两个服务器端解决方案:

  1. 在隐藏表单字段中创建一次性使用“令牌”。一旦使用了令牌,它就会从您存储它的任何数据库或会话上下文对象中删除。第二次,它不被接受。
  2. 收到缓存信息,如果在特定时间段内收到相同的表格(10分钟?一小时?您决定!),则会被忽略。

答案 3 :(得分:2)

实现uniqueid以处理请求并将其与执行一起记录。如果已经记录了id,则不会再次执行该作业。这有点像后备解决方案 - 您应该尝试禁用按钮或链接客户端以及您自己建议

答案 4 :(得分:2)

我们使用时间敏感的一次性票。这就像是排序的会话ID。但它与表单/页面相关联。

您在用户提交页面时丢弃该票证,并且您只处理有效票证附带的页面。同时,您可以通过将票证附加到用户来加强安全性,因此如果票证是由提交票证的用户提交的票证进入的,则拒绝该请求。

答案 5 :(得分:2)

如果您正在使用它,Struts会内置这样的内容。

http://struts.apache.org/1.x/apidocs/org/apache/struts/util/TokenProcessor.html

答案 6 :(得分:-2)

我使用时间戳并将值与服务器端代码进行比较。如果两个时间戳足够接近且具有相同的IP地址,请忽略第二个表单提交。