Уникальный токен с отправкой формы не работает - PullRequest
0 голосов
/ 23 февраля 2012

Вот что я хочу сделать:

Запретить пользователю отправлять форму дважды с использованием уникального токена.Я думаю, что у меня есть правильный код здесь, но он все еще не работает.Вывод «Не отправлять дважды» при первой отправке формы.Что я делаю неправильно?

<?php session_start(); ?>
<html>
<body>

<?php

 $_SESSION['token'] = md5(session_id() . time());
?>

<?php
if (isset($_SESSION['token']))
{
if (isset($_POST['token']))
{
    if ($_POST['token'] != $_SESSION['token'])
    {
       echo "Don't send twice!"; 
    }
}
}
else {

echo "Thank you for submitting";

} 

?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
<input type="text" name="bar" />
<input type="submit" value="Save" />
</form>

Ответы [ 2 ]

1 голос
/ 14 августа 2013

Концепция здесь ошибочна.

  1. Браузеры не позволяют пользователю отправить форму дважды с помощью POST. Они показывают предупреждение пользователю, говорящему об опасности, чтобы отправить форму дважды.

  2. Если пользователь загружает форму дважды, этот сценарий не может избежать двух отправок, поскольку токены различаются в обеих формах.

Я бы предложил сохранить представление в базе данных. Это гарантирует, что один и тот же сеанс (или один и тот же пользователь) может сохранить только одну запись.

1 голос
/ 14 августа 2013

Thank you for submitting никогда не будет отображаться, потому что условие для if( isset($_SESSION['token']) ) всегда выполняется, потому что вы генерируете токен и устанавливаете переменную сеанса непосредственно над этим условием if ... Именно поэтому вы всегда увидите «don» отправить дважды "после отправки в первый раз. При загрузке формы вы генерируете токен, сохраняете его в сеансе, помещаете в форму. После отправки формы вы снова запускаете скрипт сверху: Ваш токен теперь находится в переменной post. Но вы воссоздаете свой жетон сеанса. тогда вы сравниваете пост и сессию. конечно, они не совпадают, потому что вы только что сгенерировали НОВЫЙ токен, поэтому, конечно, они не равны.

Я рекомендую эту структуру для вашего кода:

<html>
<body>
<?php 
session_start(); 

//HAS THE FORM BEEN SUBMITTED?
if(isset($_POST))
{
    //THE FORM HAS BEEN SUBMITTED

    //VALIDATE THE TOKEN
    if($_POST['token'] == $_SESSION['token'])
    {
        //THE TOKEN WAS VALID, CONTINUE WITH PROCEDURES

    }
    else
    {
        echo 'Invalid token, please try again!';
    }

}
else
{
    //FORM NOT SUBMITTED YET

    $token = $_SESSION['token'] = md5( session_id() . time(). rand() ); 
    //i recommend adding rand() otherwise there is always a 1 second window in which the token could be doubled up...

    echo '<form action="'. $_SERVER['PHP_SELF'] .'" method="post">';
    echo '<input type="hidden" name="token" value="'. $token .'" />';
    echo '<input type="text" name="bar" />';
    echo '<input type="submit" value="Save" />';
    echo '</form>';
}
?>
</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...