Делаем анонимное голосование на сайте

22.05.2007

Статья о том, как устроить на сайте голосование так, чтобы
* посетители из баловства не голосовали по несколько раз,
* разработчик приложил минимум усилий.

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

Некоторые люди пользуются разными браузерами в зависимости от настроения, другие умеют менять IP-адреса как перчатки. Таких относительно редких чудес достаточно много.

Что важно? За одну условную сессию посетитель не должен проголосовать несколько раз.

Конечно, есть еще пожелания. Хорошо бы, человек, проголосовав на работе и придя домой, не кликнул бы еще разочек. То же относится и к счастливому обладателю модема, у которого на самом интересном месте разорвалось соединение. Два человека из-за одного компьютера в интернет-кафе не должны «склеиваться». И таких пожеланий много.

Соотношение между важным требованием и мини-пожеланиями — двадцать к одному.

Базовые решения

1. Никакой защиты можно не делать вообще. Вариант — мечта для программиста. Но доверие к результатам опроса исчезнет, если посетитель увидит, что голосовать можно сколько угодно раз. Поэтому хочется, чтобы человек кликнул и увидел, что второй раз не получится.

2. Делаем PHP-сессию и фиксируем факты голосования. В базу ничего не пишем. Что плохого? Если у администратора возникнут сомнения в достоверности результатов, расследования не получится. Да и сессия может закрыться, а посетитель вдруг вернется.

3. Есть еще подход без использования базы данных с куки. Здесь вообщее всё можно решить на клиентской стороне. Но у пользователя JavaScript и куки могут быть отключены. И расследования опять же не получится, случись что.

4. Записываем IP-адреса всех участников голосования и время. Делаем так, чтобы с одного адреса можно было голосовать раз в час. Недостатки? Никак не решается проблема с динамическими адресами. Зато нечистую игру уже можно разглядеть.

Именно так устроен модуль Drupal Voting. Для незарегистрированных посетителей других ограничений нет. Этот вариант я считаю сбалансированным — неплохой результат при небольших трудовых затратах. Дальше его можно улучшать.

Вообще-то есть еще вариант с сохранением в куки уникального идентификатора и записью его в базу. Но если бы мне пришлось выбирать, я бы лучше работал с IP-адресами. Проблема куки — доступность. IP-адрес поменять сложнее, чем стереть куки.

Дополнительные меры

1. IP-адрес можно доставать не из $_SERVER['REMOTE_ADDR'], а похитрее.

2. Если работать и с IP, и с куки, ситуация с динамическими адресами немного улучшится.

3. При голосовании можно спрашивать у посетителя какой-нибудь идентификатор, например, email или OpenID. Это шанс решить проблему с несколькими компьютерами и одним пользователем. Минус — посетителю нужно заполнять дополнительное поле.

4. Голосование можно сделать на AJAX. Плюс — отсеются боты, неумеющие исполнять JavaScript. Недостаток — поддержка JavaScript у некоторых пользователей выключена. И да, есть браузеры типа Opera 7.

5. Денис Болтиков предлагает продолжать работу с IP, используя базы адресов с разбивкой по странам и городам. Можно закрыть доступ всем нерусским посетителям, и заодно большинству анонимных прокси. Еще есть mod_geo.

6. Денис также говорит, что существуют готовые недорогие базы адресов анонимных прокси. А Dead Krolik советует ничего не покупать, а завести собственный черный список.

Я бы начинал с варианта «IP + задержка по времени + AJAX» и по мере необходимости добавлял бы разные защитки.

Кстати, любые дополнения и замечания очень приветствуются.

Комментарии

Юрий, 23.05.2007 09:07

Привет, Дима!

Интересная у вас с товарищами дискуссия в каментах разгорелась по поводу технологической части.

Но я так и не понимаю зачем нужны голосовалки? Как правило, большинство тыркает их просто так, не вдумываясь (сужу по себе и знакомым).

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

А если уж нужно общественное мнение — нужно опрашивать дедовскими методами 8))

Всем удачи и свежего ветерка... А то эти +30 мне....

Дмитрий Сергеев, 23.05.2007 17:05

Вообще я согласен, что львиная доля опросов носит какой-то развлекательный характер, а результаты не внушают доверия. Но всё-таки у меня есть одна задумка, и попробую поиграться с анонимными голосованиями. Интерес чисто практический :)

И «дедовские методы» тоже буду использовать. Сейчас только разберусь с дипломом, и займусь реализацией.

Ну а жара меня вполне устраивает :)

А что с dotfix? Времени нет или надоело?

Юрий, 23.05.2007 17:09

У меня сессия 8(((((((

У Анечки — тонна работы 8) Ну и в фоновом режиме поднимаем блог Люминатора по адресу http://luminator.ru/blog/ .

Пока именно от блога 4 звонка от клиентов и около 60 уников в день... Но хочется большего 8)

kodji, 24.05.2007 14:33

Бодрого дня!
Мое мнение относительно голосований такое (если интересно).
1. голосование в большинстве случаев не нужно посетителю (как ты совершенно верно заметил - 99% не участвуют в этих игрищах) - проверил опытным путем.
2. в тех случаях где оно все-таки нужно - например очень интересная и злободневная тема - подразумевается что люди, которые будут голосовать заинтересованы в голосовании и найдут минутку чтобы заполнить пару полей о себе и поле для нероботов. Естественно анонимность такого голосования вызывает сомнения, но комбинируя его с куками, и фиксацией ip можно получить очень качественные результаты.

спасибо за информацию о mod_geo )

Дмитрий Сергеев, 24.05.2007 17:15

За mod_geo Денису спасибо :)

Dead Krolik, 24.05.2007 20:56

Кстати об Ajax. Не надо думать, что это слово - спасение от ботов. Это те же самые запросы GET/POST, которые инициирует не пользователь, а яваскрипт. Ничего нового. Повторить это можно и без яваскрипта, достаточно посмотреть код или поснифать чего там браузер шлет.

Рекомендовал бы посмотреть такую штуку как Spam Karma ver. 2. (2 - потому что они там умничают, и версией 1 называют общие рассуждения о том как бороться с ботами, а 2 - это уже реализация).

P.S.Блин, по ходу тут предпросмотр каментов не работает.

Дмитрий Сергеев, 24.05.2007 21:07

Конечно, есть вещи, от которых никакой AJAX не спасет. Но думаю, что адрес back-end'а (как по-русски?) достать немного сложнее, чем атрибут action. Хотя эта не серьезная мера, чего уж там :)

Spam Karma посмотрю, спасибо.

А предпросмотр действительно не работает. Давно надо поправить.

Дмитрий Сергеев, 26.05.2007 00:29

Подлатал предпросмотр.

Юрий, 24.05.2007 21:02

Да вообще к чему вся эта паранойа, други?))

Все равно любая защита ломается. А самая лучшая защита — уважение людей.

Тот же человеческий фактор играет главную роль при взломе супермощных защит.

kodji, 24.05.2007 21:58

естесственно, любая защита ломается. Но дверь на ночь мы все равно запираем, не так ли ?

VolCh, 23.06.2008 00:25

Блокировка по IP адресу не очень хорошая идея, имхо, хоть постоянная, хоть с ограничениями. Простой пример (и реальный) - делааешь сайт и ставишь туда голосовалку "нравится сайт/не нравится), сайт анонсируешь на форуме своего провайдера, а в России (насчет остального мира не знаю) реалии таковы, что у многих просто нет выделенного IP, сидят тысячи народу под одним адресом - у одних провайдер не предоставляет в принципе, у других за отдельную плату, третьи в целях безопасности сидят за NAT'ом (сейчас мой случай, пока с Linux не разобрался, да и 6$ экономия :) 128 анлим+IP стоит столько же сколько 256 анлим), четвертые на работе делятся ссылками с коллегами. Результат всего этого - заходят 200 человек почти одновременно и только первый проголосовать может.

Я, обычно, использовал такую защиту для анонимов:
1. кука (по ней основная проверка, считать голос или нет сразу же);
2. запись в БД или лог с кукой, IP, временем (или, чаще, ссылка на лог посещений со всей инфой запроса, включая ос, браузер и реферер), ну и голос, естественно :);
3. опционально капча, как защита от ботов, но это редко;
4. свои "черные списки" IP, включая паблик анонимайзеры;
Ну и в админке (а то и просто в екселе) возможность фильтровать и сортировать по этим параметрам (обычно по дефолту сразу вывожу количество голосов по IP) и отменять массово подозрительные голоса

Плюсы такого подхода, имхо:
- честный пользователь голосует без помех, максимум капчу вводит, причем возможности накрутить случайно лишен;
- непродвинутый накрутчик накрутить не сможет;
- чуть продвинутый сможет, очистив куки и/или сменив браузер/ос, сев за соседний комп на работе/кафе, "перезвонив" и т. п., накрутить до "расследования" - вычисляется по IP (включая по маске и whois), времени голосования, строкам идентификации и т. п. в админке. Сюда же просьбы проголосовать на форумах и прочем (по рефереру);
- от продвинутого все равно не защититься :( много времени и услилий тратить не стоит, имхо, чтобы отсеять людей, способных менять IP и всякие строки идентификации браузера и ОС, не говоря уж о чистке кук. Не так их и много, да и разозлить можно так, что сетку зомби на сайт напустят, даже не для ддоса, а для накрутки голосовалки, был один такой случай, по крайней мере другого объяснения я не нашел

ITTUM, 18.08.2008 11:24

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

Очень хорошо работают опросы по социальным вопросам и действию правительства на региональных сайтах. Там число голосующих довольно большое.