0

对于用 PHP 编写的应用程序中的“确认订单”页面,我需要防止提交多个表单,这样我们就不会收到重复的订单。我试图以两种方式处理这个问题:

  1. 对于支持 javascript 的用户,提交按钮在点击时被禁用
  2. 使用表单生成令牌并存储在会话中。在第一次提交时,它们会被比较并删除会话令牌。因此,应拒绝没有匹配令牌的后续提交。这应该具有防止 CSRF 攻击的额外好处。

我知道两者都是相当标准的做法,但问题似乎仍然存在?在禁用 js 的情况下,如果我多次单击提交按钮,我将获得 X 个重复订单。

这让我觉得这个问题可能与配置有关。它托管在 lighthttpd 上,php 使用 cgi-fcgi 编译。我不完全确定这是否相关,但我对现在这怎么可能感到困惑。

服务器代码如下(为简洁起见):

<?php
    $_SESSION['token'] = uniqid('', true);
?>
<form name="myform" action="confirm" method="POST">
  <!--.... -->
 <input type="hidden" name="csrftoken" value="<?php echo $_SESSION['token']; ?>" />
 <input type="submit" name="submit" />

然后在提交时验证令牌:

<?php
   if ($_POST['csrftoken'] == $_SESSION['token']) {
       //proceed and process order
       unset($_SESSION['token']);
   }

?>

会话已启动,令牌已正确生成并随后取消设置。

我过去使用过这种方法没有任何问题,但这次似乎仍然可以通过。将不胜感激任何见解。

4

1 回答 1

0

根据 Ghigo 的评论,我重构了代码以使其工作。

该问题最终是来自 iframe 和表单提交的会话锁定问题。确保会话尽早关闭是解决此问题的关键。

于 2013-03-26T11:13:26.377 回答