WordPress как на ладони
wordpress jino

Защита от спама без плагинов WordPress

Здравствуйте! есть очень хороший способ защиты от автокоментариев, описан здесь: http://www.wordpressplugins.ru/faq/no-spam-2.html

Вот суть:

==================================================

Метод подмены полей заключается в том, что мы скрываем настоящее поле для ввода комментария 'comment' и подсовываем вместо него новое поле 'real-comment'. Для посетителей блога все останется, как прежде и они не заметят никакой разницы, а вот спам-скрипты будут пытаться заполнить стандартное поле ввода комментария со стандартным его именем 'comment'.

Если ваш шаблон использует для вывода формы комментирования новую функцию comment_form(). Откройте файл шаблона functions.php и добавьте туда код:

//добавление своего поля для ввода комментария start
add_filter('comment_form_defaults', 'change_comment_form_defaults');
function change_comment_form_defaults($default) {
	//$commenter = wp_get_current_commenter();

	$default['comment_notes_after'] .=
	'<p class="comment-form-real-comment">
	<label for="real-comment">Комментарий</label><textarea id="real-comment"
	aria-required="true" rows="8" cols="45" name="real-comment"></textarea>
	</p>';

	return $default;
}

Теперь, надо скрыть стандартное поле путем вставки в style.css кода:

.comment-form-comment {display: none;}

У нас теперь есть видимое поле для ввода комментария 'real-comment' (можно использовать другое имя), а стандартное поле скрыто с глаз посетителей.

Теперь нам надо определить, какое из полей было заполнено комментатором - если видимое, то комментарий пропускаем, а если невидимое, то запрещаем его публикацию. Для этого откройте файл functions.php вашего шаблона и добавьте туда код:

//проверка на спам start
add_filter('pre_comment_on_post', 'verify_spam');

function verify_spam($commentdata) {
  $spam_test_field = trim($_POST['comment']);
  if(!empty($spam_test_field)) wp_die('Спаму нет!');
  $comment_content = trim($_POST['real-comment']);
  $_POST['comment'] = $comment_content; 
  return $commentdata;
}
//проверка на спам end

=====================================================

Все бы ничего но с выходом WP 4.4 перестало работать, автор статьи предлагает изменить функцию проверки на спам вот так:

//проверка на спам start
add_filter('init', 'verify_spam');

function verify_spam($commentdata) {
  $spam_test_field = trim($_POST['comment']);
  if(!empty($spam_test_field)) wp_die('Спаму нет!');
  $comment_content = trim($_POST['real-comment']);
  $_POST['comment'] = $comment_content; 
  return $commentdata;
}
//проверка на спам end

то бишь вместо pre_comment_on_post использовать init. Все вроде бы работает, но при этом у многих судя по комментариям начали некоторые плагины отказывать. Собственно вопросы:

1) можно ли использовать последний измененный код, насколько он правильно функционирует и не мешает ли работе WP в целом?

2) Ваши мысли о этом способе в общем?

2
Гость 1.1 года назад
  • 0
    Kama4489

    Немного про суть. С версии 4.4. появилась функция wp_handle_comment_submission() - смотрим в код и видим, что нет ни одного фильтра, через который можно изменить поле content. Выход один, изменить $_POST заранее. Да во время init - подходит. Но последний код не проверят что вообще за запрос пришел и срабатывает для абсолютно всех запросов на сайте, поэтому могут быть глюки.

    По коду новому могу сказать, что писал его дилетант или просто быстро подправил не задумываясь о последствиях... Во-первых init это событие и ничего оно не передает, что это там за $commentdata передается и еще и потом возвращается куда-то - это секрет создателя... Впрочем это на работу кода никак не виляет. Ну и всякие trim там зачем, непонятно, и не проверяется элемент массива $_POST['comment'] а просто вызывается, что выведет заметку PHP при дебаге... В общем код рабочий, но недоделанный...

    Я бы написал так:

    // проверка запроса на спам в комментариях
    add_action('init', function () {
    	if( false === strpos($_SERVER['REQUEST_URI'], 'wp-comments-post.php') )
    		return; // выход для левых запросов
    
    	if( ! empty($_POST['comment']) )
    		wp_die('Спаму нет!');
    
    	$_POST['comment'] = $_POST['real-comment'];
    });

    Что касается стабильности этого кода: при базовом использовании ВП где форма комментов одна и комменты не используются как-то еще - этот код не будет ничему мешать. Если комменты используются где-то еще и у них есть другие типы и другие формы отправки, то он будет мешать - под него нужно будет подстраиваться и везде добавлять поле 'real-comment'...

    А еще мне не очень понятно, почему этот способ хорошо защищает от автоспама. Ведь если через бот прогу зайти на сайт и заполнить форму и далее поставить такое заполнение на автомат, то такой коммент пройдет. Неужели этого не происходит по факту? Спамеры что поголовно в файл wp-comments-post.php запросы шлют что ли?

    *Интересно, а что если не прятать старое поле, а просто заменить его новым name=real-comment? Код при этом будет работать также, но вот что будет по факту со спамом. Что-то мне подсказывает, что - спама также не будет...

    Если есть возможность поставь такое эксперимент плз - это кое что расскажет о том как работают спамеры, в большинстве своем...*

    Весь код (готовый и целиком, как мы любим)

    Для читателей, весь код. Переписал и первый код, где поле добавляется еще одно, там можно получше сделать, и display:none сразу вставить, чтобы не лазить в style.css...

    /**
     * Защита от спама в комментариях путем подмены поля комментария
     * Рассчитан на темы, где форма комментирвоания выводиться с помощью функции comment_form()
     * Добавлять код нужно в файл темы functions.php
     * v 0.1
     */
    if(1){
    	// добавление своего поля для ввода комментария
    	add_filter('comment_form_defaults', 'add_real_textarea_comment_field', 30);
    	function add_real_textarea_comment_field( $args ) {
    
    		// добавим еще одно поле textarea, точно такое как оригинальное только с name="real-comment" и спрячем оригинальное
    		if( preg_match('/<textarea.*textarea>/', $args['comment_field'], $match ) ){
    			$textarea = $match[0];
    			$real_textarea   = str_replace( 'comment', 'real-comment', $textarea, $count );
    			// если поле изменилось
    			if( $count ){
    				$hidden_textarea = str_replace( '<textarea', '<textarea style="display:none;"', $textarea );
    				$args['comment_field'] = str_replace( $textarea, "$hidden_textarea$real_textarea", $args['comment_field'] );
    			}
    		}
    
    		return $args;
    	}
    
    	// проверка запроса на спам в комментариях
    	add_action('init', function () {
    		if( false === strpos($_SERVER['REQUEST_URI'], 'wp-comments-post.php') ) return; // выход для левых запросов
    
    		if( ! empty($_POST['comment']) )
    			wp_die('Спаму нет!');
    
    		$_POST['comment'] = $_POST['real-comment'];
    	});
    }

    Свой велосипед...

    Просто не могу не порекомендовать, как альтернативу свой плагин Kama Spamblock у него принцип работы другой. Работает стабильно, защищает хорошо. Иногда бывает что кто-то подберет ключ, запостит пару спамных комментов... НО Бывает такое очень редко, раз в год примерно, ну и спама там... Я думаю, это во всех способах защиты так. Хотя, про метод этого вопроса: если найти лазейку, то спамера уже ничего не остановит...

    Евгений год назад

    Тимур Спасибо за код! Но мне на самом деле не очень хочется эксперименты проводить, хочу уже поставить и забыть, чтобы не ковыряться каждый раз если что-то обновится в WP или какие-то лазейки вскроют, или не дай бог еще блог ломанут из-за этого.

    Я бы может и поставил бы сразу твой плагин, но череда странностей меня отпугнула, а именно:

    1) когда первый раз зашел к тебе на блог пару дней назад написал и начал добавлять комментарий мне после нескольких попыток каждый раз выдавало 403 forbiden

    2) вчера добавляя коммент, у меня вылезло это окно:

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

    3) после того как коммент все таки добавился, НО он обрезался. Был довольно объемный комментарий и 3/4 его обрезалось, я так и не понял почему (в предварительном просмотре все отображалось. После чего сюда добавил вопрос.

    Уж очень не хочется чтобы мои посетители страдали геммороем при попытке прокомментировать что-либо. Прокомментируй пожалуйста Тимур?

    Kama год назад
    1. 403 forbiden - это с сервером видимо что-то было.

    2. Это несовместимость этого плагина и страничного кэша - вот этот момент я не учел. Надо подумать что можно сделать... Там nonce код устаревает и страничный кэш старый выдает... Но у меня кэш на пол дня стоит, а устаревает он за сутки, поэтому таких моментов очень мало должно быть, но это конечно неприятный момент и надо его исправить... (исправлено)

    3. Без понятия. Только что попробовал запостить огромный текст, с заблокированным комментом - через вот эту кнопку "Отправить комментарий еще раз" - текст нигде не обрезался... Был бы благодарен, если бы ты как-то показал тот текст который обрезался. Технических причин обрезки текста я вроде не вижу...

    П.С. Если способ с подменой полей помогает, то юзай его.

    Евгений год назад

    Спасибо Тимур начну с способа подмены полей, а дальше если что на плагин перейду. А комментарий был весь текст этого вопроса, я хотел его в теме с плагином добавить.

    Евгений год назад

    Тимур вставил код, попробовал коммент добавить, постоянно выдает страницу "спаму нет", в коде что-то не то?

    Kama год назад

    А новое поле textarea real-comment создалось? Очевидно отправляется с поля comment а не real-comment. Убедишь что поле заменилось... Я на локалке с темой twentyfeeftin проверю - работает!

    Комментировать
  • 0
    campusboy1837 cайт: wp-plus.ru

    Привет. Я пользуюсь сейчас или Дискусом, там спама не замечено особо, или же использую плагин Тимура (автора этого сайта) Kama Spamblock - тоже проблем не замечено (поставил и забыл, в коде даже лазить не надо).

    Евгений 1.1 года назад

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

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Регистрация. Вход.