为什么PRG模式而不是其他?

时间:2015-01-10 08:18:06

标签: java security spring-mvc web post-redirect-get

我需要阻止为客户的网站提交重复的表单。

  • 我们需要来自用户的一些表单数据以进行订单确认页面。
  • 我们对Web服务器使用负载均衡。

方法1:发布/重定向/获取

(PRG模式:http://en.wikipedia.org/wiki/Post/Redirect/GetPost/Redirect/Get

我最初尝试使用PRG模式 在这种情况下,我认为我需要跨多个Web服务器处理会话(或spring flashmap)。

方法2:在客户端上禁用刷新。

Disable refresh on client

我的一位同事提出了这种方法。

方法3:发布/发布

Post/Post

另一位同事提出了这种方法。

我认为方法2,3不是一个好的选择 但我不知道这些方法的具体缺点或安全风险 我试图谷歌,但我没有找到答案。

提前谢谢。

[编辑]

我想更新优缺点。

方法1:发布/重定向/获取

优点

  • 安全!

缺点

  • 如果您需要用户提供的某些表单数据以在确认页面上显示,则需要使用sessiondatabase或其他内容。
  • 如果您使用session并且拥有多个服务器,则必须执行某些操作以使会话可在多个服务器上使用。

方法2:在客户端禁用刷新。

优点

缺点

  • 如果限制浏览器标准功能(如刷新),用户将会感到不安。
  • 需要考虑F5,Ctrl + F5,⌘+ F5等各种刷新图标。
  • 在移动设备中,许多网络浏览器会在用户重新加载浏览器时自动刷新页面。

方法3:发布/发布

优点

  • 您不必担心跨多个服务器的会话共享问题。

缺点

  • 第二次表单提交可能会失败。

1 个答案:

答案 0 :(得分:3)

方法1是一种非常直接的方法,可以解决一些重复的帖子问题。它无法应对服务器延迟,这是重复提交的原因。

方法2只不过是错误的。如果限制浏览器标准功能(如刷新),用户将会感到不安。也就是说,如果你甚至能够通过技术上跨浏览器这样做。您需要考虑F5,Ctrl + F5,⌘+ F5等各种刷新图标。

我必须承认,我并不完全理解方法3的意图,但是,将用户反弹到空白页面感觉有点不对。

另一种标准方法是使用带表单帖子的nounce。这也可以帮助您避免称为Cross Site Request Forgery的安全风险。这很简单。

  1. 在服务器上生成一个名为nonce的“唯一”随机字符串。
  2. 将随机数插入数据库。
  3. 将nonce作为隐藏字段附加到表单(或通过URL或类似方式传递)。
  4. 确保将nonce以表单形式发送到服务器。
  5. 在服务器端验证nonce,删除nonce,“保存表单数据”。
  6. 显示确认页面。
  7. 如果您收到另一个非现有nonce的请求,那么您知道它是重复的帖子或更邪恶的CSRF攻击。

    您可能会找到some support library为您执行此操作。