【问题标题】:How do you prevent a user from posting data multiple times on a website如何防止用户在网站上多次发布数据
【发布时间】:2008-09-24 22:33:13
【问题描述】:

我正在开发一个 Web 应用程序 (J2EE),我想知道可用于处理来自浏览器的双重发布的选项。

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

  • 用户单击提交按钮后立即禁用它。
  • 遵循 POST-Redirect-GET 模式以防止在用户单击返回按钮时发送 POST。
  • 处理表单的 onSubmit 事件并使用 JavaScript 跟踪提交状态。

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

【问题讨论】:

    标签: jakarta-ee double-submit-problem


    【解决方案1】:

    很难实施防白痴的解决方案(因为他们一直在改进白痴)。 无论您做什么,客户端都可能被操纵或执行错误。

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 如何处理用户按下后退按钮(大多数浏览器不会重新请求)、更改表单中的数据并再次提交相同的“票证”?
      • 您无法阻止用户使用相同的票证重新提交新请求,但您可以在服务器端拒绝它,并显示“重复请求”错误。
      • 对,但人们是故意这样做的——提交表单,因为他们知道需要更正某些内容而回击,然后再次提交表单。他们合法使用浏览器的后退按钮来编辑记录会导致错误。
      • 当然,如果它是合法模式,那么您可以添加对它的支持 - 在服务器端,找到他们之前的请求(使用相同的票证),并根据需要更新信息。当然,这取决于您愿意接受对表单的更改多长时间。
      • 如果提交完全完成,你应该禁用令牌,或者如果提交是部分提交,你应该允许令牌被重新使用,同时处理部分提交的细节。
      【解决方案3】:

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

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

      【讨论】:

      • 1.您如何处理用户按下后退按钮(大多数浏览器不会重新请求)、更改表单中的数据并再次提交相同的令牌? 2. 如果在提交的时间段内表单的值为 A,然后用户将其更改为值为 B,然后再次将其更改回值为 A,该怎么办?那不会忽略最后的变化吗?
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          如果你碰巧在使用 Struts,它就内置了类似的东西。

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

          【讨论】:

          • 链接已损坏。
          【解决方案7】:

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

          【讨论】:

          • 操作请求服务器端解决方案
          • 我没有仔细阅读帖子,但我编辑了我的答案,所以它更符合问题。
          • 如果用户在那个时间段内真的有两位想要发布的数据怎么办?运气不好似乎是你的答案。
          猜你喜欢
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-07
          • 2011-02-24
          • 2017-04-20
          相关资源
          最近更新 更多