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

时间:2020-03-06 14:41:35  来源:igfitidea点击:

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

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

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

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

解决方案

我们可以在表格中提供"票证"作为表格的一部分,并提供一些随机数,并确保不会在服务器端两次被接受。

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

  • 在隐藏的表单字段中创建一次性使用"令牌"。一旦使用了令牌,便会将令牌从存储它的任何数据库或者会话上下文对象中删除。第二次,令牌将不被接受。
  • 接收到缓存信息,并且如果在特定时间段(10分钟?一个小时?我们决定!)中收到相同的表格,则将其忽略。

实现与请求一起处理的唯一标识,并将其与执行记录在一起。如果该ID已被记录,则无需再次执行该工作。这有点像回退解决方案,我们应该尝试禁用按钮或者链接客户端以及我们自己的建议

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

很难实现防白痴的解决方案(因为它们一直在改进白痴)。无论我们做什么,客户端都可能被操纵或者执行不正确。

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

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

当用户提交页面时,我们将丢弃该票证,而我们仅处理带有有效票证的页面。同时,我们可以通过将票证添加到用户来加强安全性,因此,如果其中包含的票证是由用户(而不是票证提交的用户)提交的,则我们拒绝该请求。

如果我们碰巧正在使用Struts,则内置了类似这样的东西。

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