【问题标题】:Why is a new token generated when we submit the form为什么我们提交表单时会生成一个新的token
【发布时间】: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()

标签: php session


【解决方案1】:

根据@FunkFortyNiner 提供的链接,我想我明白了,希望我理解正确。

会发生什么: 如果我们点击提交按钮两次,$_POST 令牌将保持不变,但 $_SESSION 令牌(在标头中定义)将改变..

来自链接:here

表单令牌的设置具有辅助安全功能。因为 PHP会话存储在服务器端,可以针对 POSTed 表单令牌和存储在服务器上的表单令牌。 这可以确保发布的表单实际上是正确的表单 而不是第三方形式。这意味着它是我们的形式。支票是一个 简单的字符串比较。

当我们点击提交 twice PHP 将重新生成令牌 twice (服务器端),但表单本身保持不变(客户端没有重新生成 HTML 标记的形式)。

换句话说,PHP 会在每次“提交”请求时重新生成令牌,但您的浏览器不会重新生成包含令牌的表单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 2019-01-01
    • 2012-03-02
    • 2017-01-27
    • 2020-04-06
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多