Защита от спама без капчи

Что такое captcha думаю все знают, не раз видели картинки с искаженным текстом на различных сайтах. Такие картинки дают возможность качественно разделить посетителей на живых людей и роботов, однако ухудшают юзабилити сайта.

Я не люблю когда JavaScript используется в различных формах ввода на столько, что их невозможно без него заполнить. Поскольку, как правило, фаерволом я его себе отключаю.
Пользуясь случаем призываю вебразработчиков создавать удобоваримые версии сайта, на случай если у пользователя отключен JavaScript, а не писать одну несчастную строчку: «У вас JavaScript не работает.». Такая версия необходима и для нормальной индексации ресурса поисковыми системами, так что не ленитесь ;)

Маленькое отступление закончил и перейду к делу. Случилось так что начал приходить всяческий спам, капчи не было в силу соображений по юзабилити. В форме отправки данных присутствовал JavaScript по техническим особенностям тех функций которые форма реализовывала на сайте. По этому раз JavaScript все равно уже есть, а капчу ставить не хотелось, то решил разобратся с ботами без капчи, незаметно для пользователей :)

А вот если бы у меня была форма без скриптов, то попробовал бы такой вариант со скрытым полем. К форме добавляем скрытое поле ( display:none). Если поле заполнено, то пользователь считается ботом. Но поскольку у меня уже использовались скрипты, то я выбрал более надежный вариант, а этот не тестил.

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

function get_r_str(string_length)
{
	var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcde...";
	var r_str = '';
	for (var i=0; i<string_length; i++) {
		var rnum = Math.floor(Math.random() * chars.length);
		r_str += chars.substring(rnum,rnum+1);
	}
	return r_str;
}

 

Далее пишем функцию превращения одной строки в другую строку, на свой вкус, вот простой пример:

function change_line(some_line)
{
	var new_line = "";
	new_line += some_line.substring(4,5);
	new_line += some_line.substring(1,4);
	new_line += some_line.substring(1,2);
	new_line += some_line.substring(5,6);
	return new_line;
}

 

Этой функции передаем в качестве параметра передаем, уже заданое, значение первого поля. Результат функции записываем во второе поле.

function init_vals()
{
	var w_str = "";
	w_str += get_r_str(8);
	document.getElementById("pole1").value = w_str;
	document.getElementById("pole2").value = change_line(w_str);
	window.setTimeout("init_vals();",1000*60*60);
}

Кусок формы:

<input type="hidden" id="pole1" name="pole1_n" value="">
<input type="hidden" id="pole2" name="pole2_n" value="">
</form>
<script language="javascript1.2" >

 init_vals();

</script>

 

По скольку многие боты не выполняют JavaScript, то в случае бота, серверный скрипт получит две пустые строки в этих полях, тем самым изобличит себя. На стороне сервера надо реализовать функцию change_line(some_line) и применить ее к строке из первого поля, а потом сравнить результат со строкой из второго поля. Если результаты совпадут, значит вероятно данные прислал живой человек, у которого включен JavaScript. Таким образом можно отсеять спамные запросы от полезных. В моем случае, такой простой вариант функции change_line(some_line) помог избавится от спама, но вы можете добавить в ее код, например зависимость от даты и тп.

Благодарю за внимание и желаю вам как можно меньше спама на ваших ресурсах :)