Защита от дублирования сообщений с использованием hashfile
Автор: Misha v.3 [10 марта 2005]
Версия: 1.13
Тэги: Спам
Основная идея данного метода защиты от дублирования постов следующая: при отображении формы добавления сообщения мы генерим уникальный UID и помещаем его в hidden поле и в hashfile на пару часов (мне кажется что пары часов достаточно чтобы сформулировать свою мысль и отправить её на сервер).
После того как пришли POST данные мы проверяем наличие в хешфайле записи с переданным UID, и если такая запись есть — добавляем сообщение и удаляем запись из хешфайла, в противном случае считаем что запись уже была добавлена ранее (двойное нажатие submit, reload) или она добавляется ручками без использования нашей формы (что нам не особенно нужно).
Ну а теперь сам код:
# путь где будут жить hashfile и lock-file
$data_dir[/../data]
# открываем хешфайл
$hashfile[^hashfile::open[$data_dir/_double]]
^if(def $form:uid){
$uid[$form:uid]
}{
^rem{ *** генерим uid и добавляем его в хешфайл на 2 часа *** }
$uid[^math:uuid[]]
$hashfile.[$uid][
$.value[1]
$.expires(2/24)
]
}
$is_show_form(1)
^if(def $form:uid){
^rem{ *** пришло $form:uid - постят данные *** }
^file:lock[$data_dir/_lock]{
^if(^hashfile.[$uid].int(0) == 1){
^rem{ *** в хешфайле есть соответствующий uid - все ок, добавляем сообщение *** }
...
^rem{ *** удаляем обработаный ключ из хешфайла *** }
^hashfile.delete[$uid]
^rem{ *** пробегаем по всем записям чтобы очистились устаревшие *** }
^hashfile.foreach[k;]{}
<p>Ваше сообщение было успешно добавлено.</p>
}{
^rem{ *** э, князь, ты не прав: не знаем мы ничего про такой uid, до свидания *** }
<p>Ваше сообщение уже было добавлено ранее.</p>
}
$is_show_form(0)
}
}
^if($is_show_form){
<form method="post" action="./">
<input type="hidden" name="uid" value="$uid" />
<i>Имя:</i><br />
<input type="text" name="name" value="$form:name" /><br />
<i>E-mail:</i><br />
<input type="text" name="email" value="$form:email" /><br />
<i>Сообщение:</i><br />
<textarea name="text">$form:text</textarea>
<br />
<input type="submit" name="action" value="Отправить" />
</form>
}
Использовать hashfile совершенно не обязательно. В качестве временного хранилища также можно использовать отдельную таблицу в БД (например heap), но с parser мне кажется применение для этих целей hashfile вполне оправданным.
Раньше для защиты от дублей я так-же пользовался hashfile, но хранил там в течении нескольких часов UID-ы записей, которые я уже добавил в БД. При таком методе в hashfile-е единовременно хранилось больше записей, к тому же не было защиты от некоторых примитивных спамеров, которые постят в форумы без открытия формы (более надежно от спама защищает другой класс, использующий описываемый тут механизм как одну из своих составных частей, поэтому в любом случае я рекомендую использовать его).
Возможен так же вариант защиты от дублирования когда UID-ы сохраняются в дополнительных столбцах таблиц гостевой/форума и т.п. с уникальным индексом, но мне подобный подход не нравится, т.к. подразумевает хранение достаточно большого количества совершенно ненужной впоследствии информации.
На самом деле можно было не читать то, что написано выше, а просто скачать класс к которому прилагается рабочий пример и делать по образу и подобию :)
Скачать:
antiflood.zip
(20.04.2007
2,3 КБ)
Класс для защиты от дублирования с примером использования.