【发布时间】:2018-07-30 17:38:24
【问题描述】:
我很难理解answer on SO。这是一种防止表单被处理两次的解决方案(如果有人连续两次单击“提交”按钮)。
它生成一个唯一的令牌并将其存储在表单中。所以如果提交按钮被点击两次它会忽略重复提交。
代码是
// form.php
<?php
// obviously this can be anything you want, as long as it is unique
$_SESSION['token'] = md5(session_id() . time());
?>
<form action="foo.php" method="post">
<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
<input type="text" name="bar" />
<input type="submit" value="Save" />
</form>
// foo.php
if (isset($_SESSION['token']))
{
if (isset($_POST['token']))
{
if ($_POST['token'] != $_SESSION['token'])
{
// double submit
}
}
}
每个人都同意这是正确的解决方案,但我不明白为什么我们第二次单击提交按钮时 $_SESSION['token'] 会发生变化。
感谢您的帮助
【问题讨论】:
-
“但我不明白为什么我们第二次单击提交按钮时 $_SESSION['token'] 会有所不同。” - 这就是背后的全部原因它;-)
-
每次加载页面时都会覆盖存储在会话中的令牌
$_SESSION['token'] = md5(session_id() . time()); -
您似乎缺少的部分是,如果
$_POST['token'] === $_SESSION['token']您更改会话中的令牌,以便如果表单提交两次,则相同的令牌发布两次,在第一次提交时更改并且第二个不匹配。 -
取决于它的动作,但是是的;它会那样做。如果您想保留相同的会话数组,请将其分配到某处并稍后使用。有点难以理解这到底是怎么回事。
-
为了防止定时攻击,不要使用
==使用hash_equals()