Как сделать защиту от повторных голосов в опросах WordPress без изменения базы данных

Диагностика проблемы: почему повторные голоса вредят опросам

Повторные голоса и накрутки искажают результаты опросов, делают аналитику недостоверной. Часто встроенные механизмы плагинов опросов не гарантируют 100% защиту от повторного голосования, особенно если база данных не должна модифицироваться (например, на хостингах с ограничениями или при использовании сторонних сервисов хранения).

Основные признаки проблемы:

  • В опросах появляются голоса с одного IP или с одного аккаунта/браузера более одного раза.
  • Отсутствует ограничение по времени между голосованиями.
  • Пользователи жалуются, что могут голосовать повторно.

Пошаговое решение: защита на уровне кук и проверки IP

1. Установка куки с отметкой о голосовании

При успешном голосовании в опросе устанавливаем cookie с уникальным идентификатором опроса. При попытке повторного голосования проверяем наличие этой куки. Такой подход прост и не требует изменений в базу.

function wppolls_set_vote_cookie($poll_id) {
    setcookie('wppolls_voted_' . $poll_id, '1', time() + 365 * DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
}

// Хук, срабатывающий после голосования
add_action('wppolls_after_vote', 'wppolls_set_vote_cookie', 10, 1);

2. Проверка наличия куки перед голосованием

Перед добавлением голоса проверяем, есть ли куки. Если есть — блокируем голос.

function wppolls_block_repeat_vote() {
    if ( isset($_POST['poll_id']) ) {
        $poll_id = intval($_POST['poll_id']);
        if ( isset($_COOKIE['wppolls_voted_' . $poll_id]) ) {
            wp_send_json_error(array('message' => 'Вы уже голосовали в этом опросе.')); 
            wp_die();
        }
    }
}

add_action('wp_ajax_wppolls_vote', 'wppolls_block_repeat_vote', 1);
add_action('wp_ajax_nopriv_wppolls_vote', 'wppolls_block_repeat_vote', 1);

3. Проверка IP-адреса по сессии

Для дополнительной защиты можно хранить IP в сессии или transient, чтобы не использовать базу данных.

function wppolls_check_ip_before_vote($poll_id) {
    if (!session_id()) session_start();
    $user_ip = $_SERVER['REMOTE_ADDR'];
    if (isset($_SESSION['wppolls_ips'][$poll_id]) && $_SESSION['wppolls_ips'][$poll_id] === $user_ip) {
        wp_send_json_error(array('message' => 'Вы уже голосовали с этого IP.'));
        wp_die();
    }
}

function wppolls_save_ip_after_vote($poll_id) {
    if (!session_id()) session_start();
    $user_ip = $_SERVER['REMOTE_ADDR'];
    $_SESSION['wppolls_ips'][$poll_id] = $user_ip;
}

add_action('wp_ajax_wppolls_vote', function() {
    if ( isset($_POST['poll_id']) ) {
        wppolls_check_ip_before_vote(intval($_POST['poll_id']));
    }
}, 0);

add_action('wppolls_after_vote', 'wppolls_save_ip_after_vote', 10, 1);

Проверка результата после внедрения

Для проверки корректности решения:

  • Откройте опрос в браузере в режиме инкогнито, голосуйте — голос должен пройти.
  • Обновите страницу и попробуйте проголосовать повторно — должно появиться сообщение об ошибке.
  • Проверьте, что в куках браузера появилась wppolls_voted_[poll_id].
  • Повторите голосование с другого браузера или с другого IP (например, через VPN) — голос должен пройти.

Частые ошибки и как их исправить

  • Куки не устанавливаются: проверьте, что setcookie() вызывается до вывода контента. Иначе куки не сохранятся.
  • JavaScript плагина не учитывает блокировку: дополнительно нужно модифицировать JS плагина, чтобы он корректно обрабатывал ошибки сервера и показывал сообщения.
  • Пользователь чистит куки: в таком случае IP-проверка помогает ограничить повторные голоса.
  • Сессии не работают: убедитесь, что сессии PHP включены и не конфликтуют с другими плагинами.

Практические советы по безопасности и производительности

  • Не храните IP пользователей в базе данных без согласия — используйте сессии или transient с ограниченным сроком.
  • Комбинируйте несколько методов (куки, IP, сессии) для лучшей защиты.
  • Для критичных опросов рассмотрите CAPTCHA или авторизацию перед голосованием.
  • Обрабатывайте ошибки AJAX-запросов на стороне клиента, чтобы улучшить UX.

Сравнение вариантов защиты от повторных голосов

МетодИзменения в базеНадежностьПроизводительностьСложность
КукиНетСредняя (куки можно чистить)ВысокаяНизкая
IP в сессииНетВыше (но IP может меняться)ВысокаяСредняя
Хранение IP в базеДа (изменение структуры)ВысокаяСредняяВысокая
Авторизация пользователейНетОчень высокаяСредняяСредняя
Как создать многоэтапный опрос в WordPress с помощью кода
24.01.2026
Создание опроса с оценкой и комментариями в WordPress
06.04.2026
Как удалить оценки и отзывы из опросов WordPress без потери данных
30.05.2026
Как разделить результаты опросов по пользователям в WordPress
14.02.2026
Как создать настройку видимости опросов в WordPress по ролям пользователей
30.03.2026