Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Защита от повторной отправки формы
 
 автор: lifead   (26.12.2008 в 10:56)   письмо автору
 
 

Доброе время суток!
В своё время меня передо мной вставала проблема, запрета повторной отправки формы из html странички. Для себя я нашёл несколько способов, вот хочу поделиться, и может кто то посоветует какие-то улучшения или другие варианты:
Вариант 1.
В этом варианте форма и обработчик должны быть в разных файлах, т.е. отправляем:
файл с html формой

<form action="<name>.php" method="POST">
Здесь может быть расположено html, php, js и т.д.
[Кнопка]
</form>

файл обработчик

код самого обработчика, написанный на php
после обработки делаем пересылку:
$st='location:<имя_любого_файла куда_хотите_вывести_пользователя_после_обработки_например_назад_на исходный_скрипт>';
header ($st);


Вариант 2

Для осуществления данного варианта необходимо прибегать к средствам php, что делает это метод менее универсальный, чем с html, но мне это не мешает :).
в файле с html формой вставляем следующий скрипт:

<?
session_start
();
if (!isset(
$_SESSION['<name_var>'])){
exit;
if (
$_SESSION['<name_var>']='exit'){
exit;}
}
?>
Текст формы... :)

в файл с обработчиком добавляем следующий скрипт

<?
session_start
();
$_SESSION['<name_var>']='exit';
?>

  Ответить  
 
 автор: DJ Paltus   (26.12.2008 в 11:00)   письмо автору
 
   для: lifead   (26.12.2008 в 10:56)
 

Есть у меня гостевушка, файловая. Ну и в плане двойной отправки я просто перед сохранением отправленного сверяю с последним сохраненным. От двойного клика и обновления страницы вполне спасает.

  Ответить  
 
 автор: lechie   (27.11.2012 в 10:18)
 
   для: DJ Paltus   (26.12.2008 в 11:00)
 

>Есть у меня гостевушка, файловая. Ну и в плане двойной отправки я просто перед сохранением отправленного сверяю с последним сохраненным. От двойного клика и обновления страницы вполне спасает.
Не поможет, если будут в одно время несколько пользователей отправлять сообщения

  Ответить  
 
 автор: root   (26.12.2008 в 11:35)   письмо автору
 
   для: lifead   (26.12.2008 в 10:56)
 

>...вот хочу поделиться, и может кто то посоветует какие-то улучшения или другие варианты:

как другой вариант могу посоветовать делать и форму и обработчик в одном файле.


>в файле с html формой вставляем следующий скрипт:
>session_start();
>if (!isset($_SESSION['<name_var>'])) {
>exit;

а с какой стати name_var тут должен быть isset?
..и exit далеко не лучший вариант.

  Ответить  
 
 автор: lifead   (26.12.2008 в 12:53)   письмо автору
 
   для: root   (26.12.2008 в 11:35)
 

DJ Paltus то, что Вы описали, это хорошо при небольших количествах обращений в единицу времени. Поясню, например когда в течении 10 секунд форму отправляет 3-6 человек, то Ваш вариант не сработает, потому, что при повторном нажатии кнопки отправить, после того как с другой машины были внесены данные, Ваши данные будут записаны вновь, потому, что они не будут совпадать с последними записанными.


root,
> >...вот хочу поделиться, и может кто то посоветует какие-то улучшения или другие варианты:
>как другой вариант могу посоветовать делать и форму и обработчик в одном файле.
В этом случае Вам необходима переменная передаваемая методом POST по которой необходимо отслеживать что запускать обработчик или форму, а не проще ли тогда вынести обработчик в отдельный файл. Или Вы имели ввиду что то другое?

>>в файле с html формой вставляем следующий скрипт:
>>session_start();
>>if (!isset($_SESSION['<name_var>'])) {
>>exit;

>а с какой стати name_var тут должен быть isset?
>..и exit далеко не лучший вариант.
Да согласен неправильно изложил материал.
Суть была в следующем, при запуске формы на сервере запускается сессия, регистрируется переменная, и в эту переменную записывается какое-то значение формируемое псевдо-случайным образом - примерно такого типа "%f37$^..84<t3".
значение этой переменной в форме записываем в поле type=hidden, которое при отправке будет передано.
В файле с обработчиком, открываем сессию, сравниваем значение полученное из поля hidden и значение переменной.
После чего переменную уничтожаем.
В этом случает мы предотвращаем повторную отправку данных, и защищаем скрипт от отправки форм с другого сервера (не помню как называется этот тип атак)

  Ответить  
 
 автор: Root   (26.12.2008 в 13:16)   письмо автору
 
   для: lifead   (26.12.2008 в 12:53)
 

>В этом случае Вам необходима переменная передаваемая методом POST по которой необходимо отслеживать что запускать обработчик или форму

так уж необходима переменная?
if(count($_POST) > 0) как вариант.


Представьте, что Вам нужно проверить правильно ли заполнены поля формы и вывести соответствующие уведомления в случае если нет, причем не потеряв введённых пользователем данных.

А от повторной отправки спасает простой header('Location: somewhere');

  Ответить  
 
 автор: SteAlzzer   (26.12.2008 в 14:06)   письмо автору
 
   для: lifead   (26.12.2008 в 12:53)
 

насчет сессий:
Как я понял, вначале имеется рандомная сессия. В handler'е мы меняем ее значение на 'exit' и пользователь свободен к возвращению
А если пользователю надо будет отправить еще какое-нибудь сообщение, а после первого сообщения его блокируют. Тоесть, другими словами, где мы присваиваем этой сессии $_SESSION['<name_var>'] такое значение, при котором пользователь сможет еще одно сообщение отправить?

  Ответить  
 
 автор: lifead   (26.12.2008 в 15:11)   письмо автору
 
   для: SteAlzzer   (26.12.2008 в 14:06)
 

Root
>>В этом случае Вам необходима переменная передаваемая методом POST по которой необходимо отслеживать что запускать >обработчик или форму

>так уж необходима переменная?
>if(count($_POST) > 0) как вариант.

Здесь с Вами согласен, но как то это слишком обобщённо, мне это не нравиться. Не безопасно.

>Представьте, что Вам нужно проверить правильно ли заполнены поля формы и вывести соответствующие уведомления в случае >если нет, причем не потеряв введённых пользователем данных.

А Вы не уничтожайте переменную в сессии раньше времени.

>А от повторной отправки спасает простой header('Location: somewhere');
Да.
-------------
SteAlzzer
>насчет сессий:
>Как я понял, вначале имеется рандомная сессия. В handler'е мы меняем ее значение на 'exit' и пользователь свободен к >возвращению
>А если пользователю надо будет отправить еще какое-нибудь сообщение, а после первого сообщения его блокируют. Тоесть, >другими словами, где мы присваиваем этой сессии $_SESSION['<name_var>'] такое значение, при котором пользователь сможет >еще одно сообщение отправить?

НЕТ! Признаю второй вариант написан КОРЯВО! Сам код в правильной его констатации (или как там) написать не получилось сходу, поэтому рассказываю логику ещё раз:
1) В файл-скрипт с формой, которая (форма) будет выдана браузером на экран пользователю, необходимо включить, код написанный на php, и который будет делать следующее:
1.1)Открывать сессию
1.2)Создавать переменную в сессии
1.3) Генерировать какое-то псевдо-случайное значение
1.4) Это псевдо-случайное значение записываем в переменную сессии
1.5) Создаём "невидимое" поле в форме и в значении value указываем переменную из сессии
2) В файле обработчике
2.1)получаем переменную передаваемую в "невидимом" поле (полученное методом GET или POST, это уже Ваше личное желание)
2.2) сравниваем его со значением в сессии и если эта переменная в сессии есть, и ее значение совпало, то происходит дальнейшая Ваша обработка данных;
2.3) После того как данные внесены в базу и работа обработчика по обработке данных закончена, уничтожаем переменную в сессии.
т.о. не даём запустить обработчик повторно, на сервере сессия уже уничтожена, и для того чтобы ему ещё раз внести данные необходимо заново загрузить форму и заполнить её.
P.S.
Вопрос о запрете умышленного повторного заполнения формы и ее последующей отправки здесь не рассматривался.

  Ответить  
 
 автор: Root   (26.12.2008 в 15:24)   письмо автору
 
   для: lifead   (26.12.2008 в 15:11)
 

Ещё раз:
Представьте, что Вам нужно проверить правильно ли заполнены поля формы и вывести соответствующие уведомления в случае если нет, причем не потеряв введённых пользователем данных.

Как Вы это собираетесь сделать?
При чём тут "не уничтожайте переменную в сессии раньше времени."?

  Ответить  
 
 автор: lifead   (26.12.2008 в 15:34)   письмо автору
 
   для: Root   (26.12.2008 в 15:24)
 

Root
>Представьте, что Вам нужно проверить правильно ли заполнены поля формы и вывести соответствующие уведомления в >случае если нет, причем не потеряв введённых пользователем данных.
>Как Вы это собираетесь сделать?
>При чём тут "не уничтожайте переменную в сессии раньше времени."?

А что Вам мешает делать проверку?
Или что Вам мешает вернуть пользователя на страницу с формой?
Или ели Вы про то что обработчик и форма в одном файле, так это пожалуйста, это Ваше личное дело в одном файле Вы хотите или в двух :).

  Ответить  
 
 автор: Root   (26.12.2008 в 17:03)   письмо автору
 
   для: lifead   (26.12.2008 в 15:34)
 

Мне ничего не мешает, мешать будет Вам, так как Вы бегаете от обработчика к форме.
но это Ваше личное дело..

  Ответить  
 
 автор: devzorg   (27.12.2008 в 23:44)   письмо автору
 
   для: lifead   (26.12.2008 в 10:56)
 

сохранить в сессии md5() от конкатенации данных полей из формы... а перед обработкой проверять ...
если текущий хеш не равен хешу из сессии тогда обработка иначе .. повторная отправка

  Ответить  
 
 автор: lifead   (30.12.2008 в 05:20)   письмо автору
 
   для: devzorg   (27.12.2008 в 23:44)
 

Это что то вроде условие с пост проверкой? я правильно понял.
Да в этом что то есть :)

  Ответить  
 
 автор: Yarovoews   (01.01.2009 в 15:37)   письмо автору
 
   для: lifead   (26.12.2008 в 10:56)
 

Вообщем.
1 Форму прошить сессий
2 Капча (!)
И ещё есть защита на javascrit, как она точно работает не знаю,
но суть в том что в диапазон значений либо положение мышки отправляются, после идёт проверка.

  Ответить  
 
 автор: sim5   (01.01.2009 в 15:46)   письмо автору
 
   для: Yarovoews   (01.01.2009 в 15:37)
 

При чем тут каптча, "прошивка сессией"?

  Ответить  
 
 автор: devzorg   (02.01.2009 в 20:57)   письмо автору
 
   для: sim5   (01.01.2009 в 15:46)
 

человек с умничать хотел)

  Ответить  
 
 автор: Николай2357   (02.01.2009 в 21:10)   письмо автору
 
   для: devzorg   (02.01.2009 в 20:57)
 

Когда хочется с умничать, надо писть слитно - сумничать. А человек помочь хотел, но не разобрался малость...

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования