Подтвердить что ты не робот

Предотвращение повторных представлений формы

Я придумал технику для предотвращения повторной подачи формы, возвращая/переместив или обновив страницу. И я подумал о том, чтобы судить об этом здесь, я уже тестировал образец не в производственной среде, какие недостатки вы можете идентифицировать?

Обратите внимание, что мне хорошо известно использование форм-токенов, которые защитят вас от атак CSRF и не будут добавлены в следующие шаги.

-Создать идентификатор формы для каждой формы и использовать его как скрытое поле в форме:

$formid = microtime(true)*10000;

- В форме submit:

  • Подтвердить данные

  • Вычислить хэш данных полей формы

    $allvals = '';
    foreach($_POST as $k=>$v){
        $allvals .= $v;
    }
    $formHash = sha1($allvals);
    
  • Проверять хэш хэшей, сравнивая с ранее сохраненными хэшами. значение сеанса привязывается к каждой форме переменной $formid.

    $allowAction = true;
    if(isset($_SESSION['formHash'][$_POST['formid']]) && ($_SESSION['formHash'][$_POST['formid']] == $formHash)){
         $allowAction = false;
    }
    
  • Если хэш не был найден, это означает, что это первая форма, представленная или данные формы изменены.
  • Если данные сохранены (например, в базе данных), сохраните хэш формы в сеансе:

    $_SESSION['formHash'][$_POST['formid']] = $formHash;
    

Полная версия кода: http://thebusy.me/2011/01/06/preventing-duplicate-form-submissions/

4b9b3361

Ответ 1

Более простой способ добиться того, что вы хотите, это использовать перенаправление на submit. После обработки запроса POST вы перенаправляете, возможно, даже на ту же страницу. Это общий шаблон, называемый "Перенаправление после POST" или POST/Redirect/GET.

Например:

<?php
if($_POST) {
    // do something

    // now redirect
    header("Location: " . $_SERVER["REQUEST_URI"]);
    exit;
}
?>

<html> ...
<form method="post" action=""> ... </form>

Установив действие на "", он будет подчиняться самому себе, после чего блок кода if ($ _ POST) будет проверять true и обрабатывать форму, а затем перенаправлять обратно к себе.

Конечно, вы, вероятно, хотите перенаправить на другую страницу, на которой отображается ответ "Ваша форма отправлена", или поместить форму на другую страницу и получить ответ на эту HTML-страницу.

Преимущество этого метода заключается в том, что когда вы нажимаете кнопку "Назад", он выполняет запрос GET, чтобы форма не была повторно отправлена.

В Firefox он фактически берет на себя представление из истории браузера, поэтому, когда пользователи просматривают веб-страницы, а затем ударяют назад, вместо того, чтобы видеть страницу "спасибо", они видят страницу формы.

Ответ 2

Похоже, вы слишком усложняетесь. Мой любимый способ, потому что он также предотвращает некоторые хаки взлома сессии в одно и то же время, описан здесь:

http://www.spotlesswebdesign.com/blog.php?id=11

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

Ответ 3

Оба вышеприведенных решения хороши, но немного коротки.

как насчет остановки дальнейших вставок в ближайшие несколько минут от одного и того же пользователя с незначительными изменениями данных?

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

возможно, кто-то может прокомментировать обоснованность и эффективность моего предложения, или я лаяю неправильное дерево???