提问人:Paolo Bergantino 提问时间:10/20/2008 最后编辑:Paolo Bergantino 更新时间:4/2/2014 访问量:16788
如何在服务器端处理多个提交
How to handle multiple submissions server-side
问:
我们都知道“禁用提交按钮”的古老技巧,但是处理服务器端多个提交的最佳方法是什么?我有一个应用程序,其中表格只发送一次是绝对关键的 - 它处理信用卡。我没有写现在的情况,但作为一个快速修复,我使用了提交时禁用技术,但是一些禁用了 javascript 的不耐烦的用户仍然被收取两次费用。
那么,有哪些方法可以避免这种情况呢?我能想到一些 - 我过去使用过一些 - 但我想看看是否有任何关于如何解决这个问题的“最佳实践”。我正在使用 PHP,但我对概念更感兴趣。
编辑:我知道令牌技术,这是我过去使用过的技术,这个问题或多或少是为了看看我的方法是否与你们其他优秀程序员使用的方法一致。
答:
一种真正有效的方法是在请求的同时提交令牌,并保留已用令牌的列表。如果令牌无效,或者令牌已被处理,则中止。
令牌可以像递增整数一样简单,存储在隐藏的文本字段中,也可以对其进行加密以提高安全性。通过在创建页面时生成令牌,对其进行加密,然后确认令牌已生成且尚未处理,可以使此功能更加可靠。
评论
在隐藏的表单字段中包含随机唯一令牌。然后在后端,您可以检查它之前是否提交过。
这通常是一个好主意,因为它也可以帮助您防御 XSS 攻击。
评论
我不会为此依赖任何客户端。为什么不在向客户端显示提交按钮之前为此事务服务器端生成一个唯一 ID?然后,客户端必须重新提交此令牌,并检查服务器端是否每个令牌都提交过一次。
正如其他人所说,令牌可以是递增整数(+ 用户名)或 GUID。
您也可以简单地测试在最后一分钟(或第二秒,取决于服务器的延迟)是否进行了相同的交易。大多数人不会使用同一张卡在一分钟内购买两本相同的书(或其他任何东西)。如果您在最后一分钟保留了信用卡付款的缓存,并检查您即将进行的付款是否与您刚刚完成的付款相同(相同的卡号,相同的金额),那么您很可能会发现重复的付款。
无需生成唯一的代币和所有这些爵士乐。表单验证通过后,只需将访问者重定向到另一个页面,上面写着“您的信用卡正在处理中”之类的内容。如果访问者重新加载页面,他们正在重新加载重定向的页面,而不是 POST 提交。
评论
我也有类似的问题。读完这篇文章后,我认为代币可能是要走的路。这篇文章展示了一个很好的实现示例。
评论