Robert Sinclair
Robert Sinclair

Reputation: 5416

Why is a new token generated when we submit the form

I'm struggling to understand an answer on SO. It's a solution which prevents the form from being processed twice (if someone clicks "submit" button twice in a row).

It generates a unique token and stores it in the form. So if the submit button is clicked twice it will ignore the duplicate submission.

Code is

    // 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
            }
        }
    }

Everyone agrees that it's the right solution, but I don't understand why the $_SESSION['token'] changes the second time we click the submit button.

Thank you for your help

Upvotes: 2

Views: 736

Answers (1)

Robert Sinclair
Robert Sinclair

Reputation: 5416

Based on the supplied link by @FunkFortyNiner I think I figured it out, hopefully I understood this correctly.

What happens: If we click the submit button twice the $_POST token will remain the same but the $_SESSION token (defined in the header) will change..

From the link: here

The setting of a form token has a secondary security function. Because PHP sessions are stored server side, a check can be made against the POSTed form token and the form token which is stored on the server. This ensures that the form being POSTed is, in fact, the correct form and not a third party form. This means it is our form. The check is a simple string comparison.

When we click submit twice PHP will regenerate the token twice (server side), but the form itself remains the same (client side hasn't regenerated the HTML markup of the form).

In other words PHP regenerates the token with each "submit" request, but your browser doesn't regenerate the form that contains the token.

Upvotes: 4

Related Questions