为啥是 PRG 模式而不是其他模式?
Posted
技术标签:
【中文标题】为啥是 PRG 模式而不是其他模式?【英文标题】:Why PRG pattern rather than others?为什么是 PRG 模式而不是其他模式? 【发布时间】:2015-03-08 13:56:36 【问题描述】:我需要防止为我客户的网站提交重复的表单。
我们需要一些来自用户的表单数据用于订单确认页面。 我们对 Web 服务器使用负载平衡。方法一:发布/重定向/获取
(PRG 模式:http://en.wikipedia.org/wiki/Post/Redirect/Get)
一开始我尝试使用 PRG 模式。 在这种情况下,我认为我需要跨多个 Web 服务器处理会话(或 spring flashmap)。
方法 2:在客户端禁用刷新。
我的一位同事建议采用这种方法。
方法 3:发布/发布
另一位同事建议采用这种方法。
我认为方法 2、3 不是一个好的选择。 但我不知道这些方法的具体缺点或安全风险。 我试图谷歌,但我没有找到答案。
提前谢谢你。
[编辑]
我想更新利弊。
方法一:发布/重定向/获取
优点
安全!缺点
如果您需要用户的一些表单数据在确认页面上显示,您需要使用session
,database
之类的。
如果您使用session
,并且拥有多个服务器,则您必须做一些事情以使会话在多个服务器上可用。
方法 2:在客户端禁用刷新。
优点
缺点
如果您限制浏览器标准功能(例如刷新),用户会感到不安。 需要考虑F5、Ctrl+F5、⌘+F5等各种刷新图标。 在移动设备中,当用户重新加载浏览器时,许多网络浏览器会自动刷新页面。方法 3:发布/发布
优点
您不必担心跨多个服务器的会话共享问题。缺点
第二个表单提交可能会失败。【问题讨论】:
【参考方案1】:方法 1 是一种非常直接的方法,可以解决一些重复的帖子问题。它无法应对服务器延迟,这是重复提交的原因。
方法 2 是错误的。如果您限制浏览器标准功能(例如刷新),用户会感到不安。也就是说,如果您甚至能够在技术上跨浏览器这样做。您需要考虑 F5、Ctrl+F5、⌘ + F5 等各种刷新图标。
我必须承认我并不完全理解方法 3 的意图,但是,将用户退回到空白页面感觉有点不对。
另一种标准方法是在表单帖子中使用公告。这也将帮助您避免称为Cross Site Request Forgery 的安全风险。这很简单。
-
在服务器上生成一个“唯一”随机字符串,称为 nonce。
将随机数插入数据库。
将 nonce 作为隐藏字段附加到表单(或通过 URL 或类似方式传递)。
确保随机数以表单形式发送到服务器。
在服务器端,验证 nonce,删除 nonce,“保存表单数据”。
显示确认页面。
如果您收到另一个带有不存在 nonce 的请求,那么您就知道它是重复的帖子或更邪恶的 CSRF 攻击。
您可能会找到为您执行此操作的 some support library。
【讨论】:
方法3的意图,正如我所说,我们需要用户提供一些表单数据(例如用户选择的颜色),并需要在确认页面上显示。 在PRG模式中,我们可以使用session。但由于我们使用多个 Web 服务器,会话共享或其他工作是一项额外的工作。 我们可以在重定向时使用参数,但我认为在url中显示用户的订单数据并不是一个好主意。 所以,从提交页面发送“用户表单数据”以轻松确认页面,我的同事建议方法 3。 好的,nonce 方法不依赖于共享会话 - 它依赖于我猜你已经拥有的共享数据库。以上是关于为啥是 PRG 模式而不是其他模式?的主要内容,如果未能解决你的问题,请参考以下文章
关于 std::cout,为啥使用“外部”而不是“单例模式”
为啥 SQL Server 不允许我启用混合身份验证模式,以便我可以使用 sa 用户将角色分配给其他用户?