Уникальный токен с формой submit не работает

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

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

<?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> 

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

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

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

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

Thank you for submitting никогда не будет отображаться, потому что условие if( isset($_SESSION['token']) ) всегда выполняется, потому что вы генерируете токен и устанавливаете переменную сеанса непосредственно над этим предложением if … Это также почему вы всегда будете видеть «не отправлять дважды» после отправки в первый раз. При загрузке формы вы создаете токен, сохраните его в сеансе, поместите в форму. После отправки формы вы снова начинаете сценарий сверху: ваш токен теперь находится в переменной 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>