PDA

Просмотр полной версии : Кнопка "Отправить". Защита от повторного нажатия.


dj_pont
08.10.2009, 21:45
Суть проблемы. Есть форма отправки с полями. Но защиты от флуда нет никакой, т.е. сиди и жми сколько хочешь на отправить.
1) Как сделать ограничение на нажатие кнопки. Т.е. не чаще одного раза в минуту допустим.
2) Как запретить прямое обращение к скрипту. На пхп это легко решается сессиями, а вот как защититься на флеше, т.е. сделать ограничения на отправку одного и того же сообщения несколько раз.
Сам скрипт отправки реализован на пхп. Но чтобы реализовать сессии, надо чтобы при загрузке формы, открылась сессия, на пхп бы при загрузке было:
session_start();
if($_SESSION['uid'] =='') {$_SESSION['uid'] = mt_rand(100000,999999);
далее его бы перехватили в скрипте отправки, но вот как запустить сессию на флеше, видимо никак...или как?

incoob
08.10.2009, 23:45
Даете клиенту идентификатор. Отправляете на сервер сообщение с идентификатором. Если в течении последней минуты клиент с таким идентификатором что-то отправлял, то игнорируете его запрос.

Второй раз за день пишу одно и то же, читайте форум внимательнее...

dj_pont
09.10.2009, 00:56
Даете клиенту идентификатор. Отправляете на сервер сообщение с идентификатором. Если в течении последней минуты клиент с таким идентификатором что-то отправлял, то игнорируете его запрос.

Второй раз за день пишу одно и то же, читайте форум внимательнее...

Ну общую суть я и так понимаю, что надо что-то присвоить, а потом сверить. Просто я пхп программист, а не AS, поэтому для меня присвоить идентификатор во флеш ничего не говорит. Как на практике это реализовать, примерный код, я так понимаю не обойдётся без xml или txt...

и как всё же сделать ограничение по нажатии кнопки, чтобы не тупо просто не отправлялась, а именно шло ограничение, что слишком часто нажимается кнопка?

wvxvw
09.10.2009, 01:03
Поместить клиента в ускоритель частиц - или просто привязать ему руки к стулу. Вы можете например сверять время последней отпавки при нажатии или еще что-то похожее, но это никак не помешает клиенту забить на вашу "умную" кнопку и отпавить запрос вообще на нее не нажимая. Всю логику вам нужно организовывать, очевидно, на PHP, флеш тут абсолютно ни при чем.

dj_pont
09.10.2009, 06:23
Поместить клиента в ускоритель частиц - или просто привязать ему руки к стулу. Вы можете например сверять время последней отпавки при нажатии или еще что-то похожее, но это никак не помешает клиенту забить на вашу "умную" кнопку и отпавить запрос вообще на нее не нажимая. Всю логику вам нужно организовывать, очевидно, на PHP, флеш тут абсолютно ни при чем.

И что мне почерпнуть из этого поста???
Я понимаю, что если я хочу чтобы на кнопку нажимали один раз в 60 секунд, то надо отталкиваться от последнего нажатия + 60 секунд, вопрос как это реализовать во флеш?!
Я понимаю, что кнопку можно обойти, в пхп я использую для этого сессии, да и саму суть, была нажата кнопка или нет, и без кнопки никуда ничего не уйдёт, только как сделать подобие сессии во флеш совместно с пхп, формы отправки и посылкка переменных то во флеш происходит, а приём этих переменных и проверку уже пхп производит, так как их сдружить на проверку сессии, или что-то похожее?!

incoob
09.10.2009, 09:03
Отправление пост запросов во флеше - urlloader. Смотрите туда.

Как вам уже сказали - во флеше надо только отправлять по клику что-то(вешаем на кнопку событие (addeventlistener) и отправляем запрос). Вся логика делается на стороне сервера. Например, создается таблица в бд, в которой хранятся идентификаторы пользователей и даты послежниъ отправленых ими сообщений. Дальше понятно должно быть...

dimarik
09.10.2009, 10:40
только как сделать подобие сессии во флеш совместно с пхп, формы отправки и посылкка переменных то во флеш происходит, а приём этих переменных и проверку уже пхп производит, так как их сдружить на проверку сессии, или что-то похожее?!

А флешка использует в качестве транспорта движок браузера. Т.о. Ваша сессия преспокойно отправится "из флеша".

dj_pont
09.10.2009, 20:31
Отправление пост запросов во флеше - urlloader. Смотрите туда.

Как вам уже сказали - во флеше надо только отправлять по клику что-то(вешаем на кнопку событие (addeventlistener) и отправляем запрос). Вся логика делается на стороне сервера. Например, создается таблица в бд, в которой хранятся идентификаторы пользователей и даты послежниъ отправленых ими сообщений. Дальше понятно должно быть...

Отправляю и принимаю переменные я с помощью "LoadVars();", а нажатие кнопки фиксирую как send.onPress=function():Void {
s_and_1_obj.t1=t1.text;
s_and_1_obj.t2=t2.text;
s_and_1_obj.receiver_mail=receiver_mail.text;
s_and_1_obj.subject=subject.text;
s_and_1_obj.t3=t3.text;
s_and_1_obj.sendAndLoad("help.php", rec_obj, "POST");
info.text="Ваше сообщение отправляется. Подождите...";
};. Я так понял, что чисто на стороне флеша ни одно из антифлуд средств не организовать?!

А флешка использует в качестве транспорта движок браузера. Т.о. Ваша сессия преспокойно отправится "из флеша".

Это я понимаю, но как стартануть сессию на стороне флеш session_start(); if($_SESSION['uid'] =='') {$_SESSION['uid'] = mt_rand(100000,999999) при открытии формы?

wvxvw
09.10.2009, 21:20
При чем тут LoadVara и AS3?
Как вы собираетесь "стартовать сессию" на клиенте?
Если вы хотите нажимать на кнопку 1 раз в 60 секунд, это совсем не значит, что пользователь тоже этого хочет. Мало того, для того, чтобы послать запрос который отправляется вашей кнопкой эта ваша кнопка абсолютно не нужна. Поэтому и пытаться предотвратить многократные нажатия на стороне клиента бессмысленно - вам нужно на сервере проверить частоту с которой приходят запросы, и если кто-то посылает запросы чаще, чем нужно - забанить его, или просто игнорировать, зависит от ситуации. Флеш тут вам в этом абсолютно не помощник.

dj_pont
09.10.2009, 21:40
При чем тут LoadVara и AS3?
Я то откуда знаю?

Как вы собираетесь "стартовать сессию" на клиенте?
Смотря что вы называете клиентом?! Если swf файл, который подгружает юзер, то допустим при подгрузке определённой сцены или при проведении мышкой над определённой зоной, а лучше, при установке курсора в одно из полей для заполнения, отсылалась бы переменная, которая стартовала сессию и передавала обратно сгенирированный код, который в дальнейшем при нажатии на кнопку передастся для сверки.

Если вы хотите нажимать на кнопку 1 раз в 60 секунд, это совсем не значит, что пользователь тоже этого хочет.
А его не будут спрашивать, хочет или нет.

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

Поэтому и пытаться предотвратить многократные нажатия на стороне клиента бессмысленно - вам нужно на сервере проверить частоту с которой приходят запросы, и если кто-то посылает запросы чаще, чем нужно - забанить его, или просто игнорировать, зависит от ситуации.
Мне со стороны флеш не нужна проверка частоты отсылки данных. Уберём всё что я писал выше, допусти сделали мощную флешку ввиде одной единственной кнопки и всё, больше абсолютно ничего нет, не надо ничего никуда передавать, в том числе и сторонних php скриптов. Реально ли прикрутить к данной кнопке действие, которое будет подщитывать во сколько было сделано нажатие и при повторном нажатии
в течении 1 минуты выдовалось сообщение о том, что вы слишком часто нажимаете кнопку.

wvxvw
09.10.2009, 22:06
Я то откуда знаю?

Предполагается, что вы знаете, на каком языке пишете

Смотря что вы называете клиентом?! Если swf файл, который подгружает юзер, то допустим при подгрузке определённой сцены или при проведении мышкой над определённой зоной, а лучше, при установке курсора в одно из полей для заполнения, отсылалась бы переменная, которая стартовала сессию и передавала обратно сгенирированный код, который в дальнейшем при нажатии на кнопку передастся для сверки.
Тут читаем про то, что такое клиент:
http://en.wikipedia.org/wiki/Client_%28computing%29
Это не я называю, это терминология общего употребления. Знание и понимание этой терминологии необходимо для создание интернет приложений.

А его не будут спрашивать, хочет или нет.

Это клиент вас не будет спрашивать, смешной вы однако :)

Поверьте нужна, без кнопки прямое обращение к скрипту ничего не даст.

Мне - даст, я даж может вашу ХТМЛ страницу загружать не буду, зависит по обсоятельствам.

Мне со стороны флеш не нужна проверка частоты отсылки данных. Уберём всё что я писал выше, допусти сделали мощную флешку ввиде одной единственной кнопки и всё, больше абсолютно ничего нет, не надо ничего никуда передавать, в том числе и сторонних php скриптов. Реально ли прикрутить к данной кнопке действие, которое будет подщитывать во сколько было сделано нажатие и при повторном нажатии
в течении 1 минуты выдовалось сообщение о том, что вы слишком часто нажимаете кнопку.

Для того, чтобы узнать время с начала запуска SWF - getTimer(), узнать дату в системе клиента - new Date()

dj_pont
09.10.2009, 22:46
Предполагается, что вы знаете, на каком языке пишете
Я знаю на каком языке пишу. А вот к сожалению понять истинную суть вашего вопроса моих экстрасенсорных возможностей не хватило. И уж тем более ответить на вопрос, который не понятен к чему и зачем был задан я тоже не смог.

Тут читаем про то, что такое клиент:
http://en.wikipedia.org/wiki/Client_%28computing%29
Это не я называю, это терминология общего употребления. Знание и понимание этой терминологии необходимо для создание интернет приложений.
К счастью я живу в России и являюсь коренным носителем русского языка и для меня скорее всего подойдёт вот эта ссылка: http://ru.wikipedia.org/wiki/%D0%9A%D0%BB%D0%B8%D0%B5%D0%BD%D1%82. На нём указано несколько значений данного слова и если вы хотите чтобы вам адекватно отвечали, то уточнайте ваши мысли. Для меня клиент, это тот человек, который оставит заявку. Я так предполагаю вы имели ввиду это: Клиент — это аппаратный или программный компонент вычислительной системы, посылающий запросы серверу. Соответственно как я и написал выше, это тот самый SWF файл, и для этого мне совсем не нужно было ходить в информационные сайты, хватило технического высшего образования.


Это клиент вас не будет спрашивать, смешной вы однако :)
Может я и смешной, а вы наивный =)

Мне - даст, я даж может вашу ХТМЛ страницу загружать не буду, зависит по обсоятельствам.
Запросы отправляет скрипт на сервер. А скрипт проверять будет:
1) Откуда вы собственно пришли. Обычный юзер не сможет попасть на форму сразу, ему надо будет нажать на страницу с сайта, т.е. реферер. (на странице точно также проверяется сессия, которая стартовала на главной, опять же число 10000-999999)
2) Клиент-Браузер, который подгружал страницу, если его нет или он левый, то простите пролетаете.
3) Была ли физически нажата кнопка. (название переменной вряд ли угадаете, хотя её тоже можно генирировать))))
4) Передано случайное число для сверки. (10000-999999)
Поэтому необходимым вам обстоятельством будет удача в гадании всех этих переменных, может 1 из 1*10 в степени где-нить 6 хотя-бы, случай и будет счастливым, что вряд ли.

Для того, чтобы узнать время с начала запуска SWF - getTimer(), узнать дату в системе клиента - new Date()
Уже ближе. Осталось понять, может ли флеш зафиксировать переменную new Date() при активации поля ввода и прибавить к этой переменной 60 секунд.

mooncar
10.10.2009, 00:16
Вам пытаются объяснить, что всю защиту нужно строить на стороне сервера средствами php, флеш тут ни при чем.
Загружаем ваше приложение в FireFox, включаем HttpFox, нажимаем в приложении "отправить", в HttpFox смотрим, копируем, какой полностью запрос пошел, со всем содержимым - URL скрипта, заголовками, данными, содержанием POST-полей и тд. И потом повторяем это запрос с любой частотой и полностью повторив запрос побайтно.
Поставьте себе FF и HttpFox, посмотрите, что происходит, когда мы работаем с флешкой, которая общается с серверными скриптами. Многое вам станет ясно и не нужно будет так много лишних слов.

1. Случай 1 - у вас приложение грузится в браузер прямо на странице. Делаем защиту на стороне сервера.

Делайте обыкновенную защиту от флуда средствами PHP. Стартуете сесиию при загрузке страницы с флешкой, в своем скрипте и делаете проверку на повтор и т.д. Вам карты в руки, как все организовать. Забудьте о флеше вообще. После загрузки страницы флешка находится на компе пользователя, загружена в браузер. Вам же говорили, что флеш никакие запросы сам не делает, от ее имени с сервером работает браузер (точнее, браузер общается с сервером от имени флеш-плеера). Клиент - это браузер, а не флеш. Флешка лежит себе в кэше, как и другие элементы страницы и при этом она еще нарисована в окне браузера на загруженной странице.
делать что-то во флеше для предотвращения флуда - неправильно.

2. Случай 2 - у вас приложение работает отдельно от браузера. Делаем защиту на стороне сервера.

Даже если у вас приложение работает не из браузера, а из проектора или stand-alone плеера, все равно всю проверку нужно осуществлять на стороне сервера - организовать эмуляцию сессии искусственно. Как?
Например, при первой отправке, когда используете sendAndLoad передавать в ответ флешке сгенерированный уникальный идентификатор и при этом фиксировать время. То есть делать запись в БД - "idr43876r834" - "2009-18-11 21:00:18"
При повторном обращении флешка передает полученный id и сервер (скрипт отправки) обязан проверять id и смотреть, можно ли отвечать или нет, достаточно ли времени прошло.
Если прошло достаточно времени, то пусть скрипт отправки отвечает "OK" и отправка происходит, а в БД фиксируется новое время для этого id.
Стирать полностью запись в БД можно по какому-то таймауту.

3. Случай 3. Делаем защиту от флуда на стороне флешки.

Если все-таки пожелаете во флеше все организовать, метод setTimeout() вам поможет. Но, повторюсь, это не будет 100%-й защитой.
Просто при первой отправке ставите свойство enabled = false для кнопки "Отправить" и одновременно с этим выставляете таймер.
По истечени времени таймер должен будет дернуть функцию, которая опять сделает для кнопки enabled = true и все:

send_btn.onRelease = function () {
lv.sendAndLoad(.....); //отправляем данные, дергаем серверный скрипт
this.enabled = false ; //деактивируем кнопку
id = setTimeout(enableBtn, 10000); //через 10 сек. кнопка опять "включится" для использования
}

function enableBtn() {
send_btn.enabled = true ; //активируем кнопку
}

wvxvw
10.10.2009, 03:47
Кроме того, ставить защиту "от пользователя" - бессмысленно потому, что пользователи, как правило, безобиные, защищать надо от программ, которые притворяются пользователями. HTTFox - довольно безобидная утилита, кроме нее существует масса анализаторов трафика и даже специального софта заточенного для отправки спама куда угодно. HTTP_REFERRER и USER_AGENT подделываются на ура если нужно, это не защита, а филькина грамота. Иногда усложняет жизнь другим, вполне себе легитимным приложениям, а от спаммеров оно как мертвому припарка.

dj_pont
10.10.2009, 04:22
Вам пытаются объяснить, что всю защиту нужно строить на стороне сервера средствами php, флеш тут ни при чем.
А я пытаюсь объяснить, что чёрт с защитой, я её на пхп организовал, мне нужна тупа кнопка с таймером!!!

Загружаем ваше приложение в FireFox, включаем HttpFox, нажимаем в приложении "отправить", в HttpFox смотрим, копируем, какой полностью запрос пошел, со всем содержимым - URL скрипта, заголовками, данными, содержанием POST-полей и тд. И потом повторяем это запрос с любой частотой и полностью повторив запрос побайтно.
Поставьте себе FF и HttpFox, посмотрите, что происходит, когда мы работаем с флешкой, которая общается с серверными скриптами. Многое вам станет ясно и не нужно будет так много лишних слов.
Вы вчитайтесь что я пишу и не будет лишних слов с вашей стороны. Будут сессии! После первой же успешной отправки будет удалена сессия, и по старой вы уже никуда ничего не отошлёте. Хоть HttpSuperMegaFox - он перехватит существующую сессию, которые выполниться только ОДИН раз!!! И ещё раз скажу, что можно реализовать динамическую переменную, который ваш хттпфокс перехватит, а в следующий раз, оп, о чудо, другая переменная, а в третий раз ещё другая... Прочитайте мануал по пхп и сессиям.

1. Случай 1 - у вас приложение грузится в браузер прямо на странице. Делаем защиту на стороне сервера.

Делайте обыкновенную защиту от флуда средствами PHP. Стартуете сесиию при загрузке страницы с флешкой, в своем скрипте и делаете проверку на повтор и т.д. Вам карты в руки, как все организовать. Забудьте о флеше вообще. После загрузки страницы флешка находится на компе пользователя, загружена в браузер. Вам же говорили, что флеш никакие запросы сам не делает, от ее имени с сервером работает браузер (точнее, браузер общается с сервером от имени флеш-плеера). Клиент - это браузер, а не флеш. Флешка лежит себе в кэше, как и другие элементы страницы и при этом она еще нарисована в окне браузера на загруженной странице.
делать что-то во флеше для предотвращения флуда - неправильно.
Спасибо, хоть кто-то понял что я не экстрасенс. Теперь понятно что имелось ввиду. Я так и организовал уже, всё на пхп.

2. Случай 2 - у вас приложение работает отдельно от браузера. Делаем защиту на стороне сервера.

Даже если у вас приложение работает не из браузера, а из проектора или stand-alone плеера, все равно всю проверку нужно осуществлять на стороне сервера - организовать эмуляцию сессии искусственно. Как?
Например, при первой отправке, когда используете sendAndLoad передавать в ответ флешке сгенерированный уникальный идентификатор и при этом фиксировать время. То есть делать запись в БД - "idr43876r834" - "2009-18-11 21:00:18"
При повторном обращении флешка передает полученный id и сервер (скрипт отправки) обязан проверять id и смотреть, можно ли отвечать или нет, достаточно ли времени прошло.
Если прошло достаточно времени, то пусть скрипт отправки отвечает "OK" и отправка происходит, а в БД фиксируется новое время для этого id.
Стирать полностью запись в БД можно по какому-то таймауту.
Вот это я и пытался услышать. С этим всё понятно, но если флешка одна, как её попросить получить запрос с идентификатором. Я про что и говорил, что мне надо бы, чтобы этот запрос пошёл когда мышка активирует поле ввода текста, т.е. тупо тыкаем в поле воода и переменная пришла. Чтобы скрипт не генерил иды при загрузке флеша.

3. Случай 3. Делаем защиту от флуда на стороне флешки.

Если все-таки пожелаете во флеше все организовать, метод setTimeout() вам поможет. Но, повторюсь, это не будет 100%-й защитой.
Просто при первой отправке ставите свойство enabled = false для кнопки "Отправить" и одновременно с этим выставляете таймер.
По истечени времени таймер должен будет дернуть функцию, которая опять сделает для кнопки enabled = true и все:

send_btn.onRelease = function () {
lv.sendAndLoad(.....); //отправляем данные, дергаем серверный скрипт
this.enabled = false ; //деактивируем кнопку
id = setTimeout(enableBtn, 10000); //через 10 сек. кнопка опять "включится" для использования
}

function enableBtn() {
send_btn.enabled = true ; //активируем кнопку
}
Вот за это СПАСИБО. Мне это и надо, это не защита от флуда, это защита от левых нажатий кнопки.

Добавлено через 8 минут
Кроме того, ставить защиту "от пользователя" - бессмысленно потому, что пользователи, как правило, безобиные, защищать надо от программ, которые притворяются пользователями. HTTFox - довольно безобидная утилита, кроме нее существует масса анализаторов трафика и даже специального софта заточенного для отправки спама куда угодно. HTTP_REFERRER и USER_AGENT подделываются на ура если нужно, это не защита, а филькина грамота. Иногда усложняет жизнь другим, вполне себе легитимным приложениям, а от спаммеров оно как мертвому припарка.

Именно поэтому будут работать все 4 метода одновременно. В 3-х из них каждый раз генериться случайное число уничтожающееся при первой же успешной отправке. И ни один скрипт не сумеет это сделать...Ну может только супр-машина какая, раз в год и сможет подобрать 3 числа, что они совпадут, так увеличить диапозон от 10000 до 99999999999999, тогда пару веков может и хватит...

mooncar
10.10.2009, 04:42
мне надо бы, чтобы этот запрос пошёл когда мышка активирует поле ввода текста, т.е. тупо тыкаем в поле воода и переменная пришла. Чтобы скрипт не генерил иды при загрузке флеша.
Если я вас верно понял, вам нужно просто при получении фокуса полем ввода делать запрос к серверному скрипту на получение id:

var id:String ; //уникальный id

var lv_load:LoadVars = new LoadVars();

input_tf.onSetFocus = function() { //при получении полем фокуса незаметно идет запрос на ID
lv_load.load('http://www.site.ru/id_generator.php', lv_load); //запрос на id
};

lv_load.onLoad = function(success:Boolean) {
if (success) {
id = this.id; //получение ответа с новым id
}
};


Если мы хотим гарантировать одноразовость получения ID, сделаем проверку на определенность переменной:

var id:String ;

var lv_load:LoadVars = new LoadVars();

input_tf.onSetFocus = function() {
if (id == undefined) { //если идентификатор еще не получен после запуска флешки
lv_load.load('http://www.site.ru/id_generator.php', lv_load);
}
};

lv_load.onLoad = function(success:Boolean) {
if (success) {
id = this.id;
}
};

Таким образом повторноые получения полем ввода фокуса (то есть клика мышкой на нем) не приведут к повторному запросу ID.
Еще желательно, наверное, отключить получение полем фокуса при нечаянном нажимании на TAB, чтобы запрос шел только при явной установке курсора на поле, это тоже можно сделать...

dj_pont
29.11.2009, 04:59
3. Случай 3. Делаем защиту от флуда на стороне флешки.

Если все-таки пожелаете во флеше все организовать, метод setTimeout() вам поможет. Но, повторюсь, это не будет 100%-й защитой.
Просто при первой отправке ставите свойство enabled = false для кнопки "Отправить" и одновременно с этим выставляете таймер.
По истечени времени таймер должен будет дернуть функцию, которая опять сделает для кнопки enabled = true и все:


Код AS1/AS2:
send_btn.onRelease = function () {
lv.sendAndLoad(.....); //отправляем данные, дергаем серверный скрипт
this.enabled = false ; //деактивируем кнопку
id = setTimeout(enableBtn, 10000); //через 10 сек. кнопка опять "включится" для использования
}

function enableBtn() {
send_btn.enabled = true ; //активируем кнопку
}

А вот в этом варианте можно как-то выдавать предупреждения при нажатии на выключенную кнопку?

mooncar
29.11.2009, 16:00
А вот в этом варианте можно как-то выдавать предупреждения при нажатии на выключенную кнопку?
Да пожалуйста - тогда ее не нужно напрямую деактивировать, а нужно просто видоизменить функцию и ввести триггер ожидания:
var wasClikced:Boolean = false ;

send_btn.onRelease = function () {
if (!wasClicked) {
lv.sendAndLoad(.....); //отправляем данные
wasClicked = true ;
id = setTimeout(resetButtonState, 10000); //через 10 сек. триггер wasClikced опять станет = false
}
else {
message_tf.text = 'Слишком частое нажатие, нужно подождать!';
}
}

function resetButtonState() {
wasClicked = false ;
message_tf.text = '';
}

dimarik
30.11.2009, 10:31
Как вариант, решение по управлению flow переложить на плечи контроллера.
var flag:Boolean = false;

function controlUIButton():Void {
switch (arguments.caller) {

case sendButton.onRelease:
trace('sendButton.onRelease occured');
if (flag) {
trace('Рано нажимать!')
return;
}

flag = true;
this.sendData();
break;

case closeButton.onRelease:
trace('closeButton.onRelease occured');
break;

default:
throw new Error('Unhandled dispatcher');
}
}

function sendData():Void {
trace('send some data to somewere')
}

sendButton.onRelease = function():Void {
controlUIButton();
};

closeButton.onRelease = function():Void {
controlUIButton();
};