Защита от спама без каптчи. Плагин.


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

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

Первое, что надо сделать — зарегистрироваться на сайте Akismet и получить ключ API. (Там просит регистрацию на Wordpress.com, т.к. класс изначально под него заточен был). Затем перейти на страницу с плагинами и библиотеками, выбрать и загрузить класс PHP 5 Akismet.

Загруженный файлик akismet.class.php кидаем в assets/lib/

Далее создаем табличку для нежелательных ip чтобы сразу блокировать ip с которых рассылался спам.

Инструменты -> Резервное копирование -> Восстановить -> Выполнить произвольную команду SQL.

CREATE TABLE IF NOT EXISTS `modx_ip_blocked` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(16) NOT NULL,
  `blocked` tinyint(4) NOT NULL,
  `when` varchar(18) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `ip` (`ip`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


Далее создаем плагин на события OnBeforeLoadDocumentObject и OnLoadWebPageCache и вставляем следующий код:

//<?php
$blockip = 1; //Блокировать пользователей по ip. 1 - да. 0 - нет.
$e = $modx->Event;
if ($e->name == 'OnBeforeLoadDocumentObject' || $e->name == 'OnLoadWebPageCache')
{
	if ($blockip) 
	{
	 	$ip = $_SERVER["REMOTE_ADDR"];
		 $tbl = $modx->getFullTableName('ip_blocked');
		 if ($modx->db->getValue("Select count(*) from $tbl where `ip`='$ip'")==1)
		 {
			 exit('Welcome to the blacklist!');			
		 }
	}
	if (($_POST['name']) || ($_POST['email']) || ($_POST['message']))
	{
		require_once ('assets/lib/akismet.class.php');
		$akismet = new Akismet('http://site.com/', '905c97472xxx');
		
		$akismet->setCommentAuthor($_POST['name']);
		$akismet->setCommentAuthorEmail($_POST['email']);
		$akismet->setCommentContent($_POST['message']);
		if($akismet->isCommentSpam())
		{
			$modx->db->insert(array('ip'=>$ip,'blocked'=>1,'when'=>time()),$tbl);
			exit('Welcome to the blacklist!');
		}
	}
	
}


Данная конструкция проверяет имя пользователя, его email и само сообщение. В примере выше используется имя поля message. Если у вас другое имя — поменяйте на ваше.

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

3 комментария

avatar
Работать будет в обоих случаях? prntscr.com/evp355
avatar
так какая разница? Мы же проверяем POST запрос до отправки каким-либо образом…
avatar
Спасибо, буду пробовать.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.