Отказ от ответственности! Я ни в коей мере не претендую на роль разработчика идеальной капчи или изобретателя чего-то нового.
Все написанное здесь было сделано мной в образовательных целях и с открытым исходным кодом.
И да, я понимаю, что написание собственной капчи — это изобретение велосипеда.
С чего все началось
Совсем недавно я начал разработку своего пока еще небольшого проекта на ASP.NET MVC 3. Суть его в том, что посетители могут добавлять в него свои сообщения, которые впоследствии появляются в открытом доступе (кому интересно, что стоит за этим запутанным объяснением - ссылка будет в конце).Понятно, что раз речь идет о публичном проекте с возможностью размещения на сервере любого контента, то необходимо позаботиться о защите от спамеров и других неприятных личностей.
Другими словами, вам нужна капча.
Первое, что пришло мне на ум, — это ReCaptcha от Google. Установив его и попользовавшись некоторое время, я наконец понял, что этот монстр совсем не для меня и не для большинства адекватных людей, особенно русскоязычных (вывод некоторых изображений не только не машиночитаем, но и не может быть читают люди тоже).
Искав другие решения, я, к своему сожалению, не нашел чего-то нормального для MVC 3, простого и ненавязчивого в использовании.
Были разные мануалы, как сделать то или иное, но готового решения «выбери и пользуйся» как-то не было.
Поэтому я решил изобретать велосипед напишите свою капчу.
Идея
Хоть поиск готовых решений и не дал мне окончательного результата, но дал идеи, как все это можно реализовать.Я решил, что мне вряд ли удастся сделать качественную капчу в том виде, в каком мы ее обычно видим (простое распознавание символов на картинке), из-за простоты ее машинного анализа.
В этом случае мне снова придется выбирать либо сложность чтения, либо слабая защита.
Поэтому я решил сделать капчу немного нестандартной, а именно отображать арифметические действия на изображении, чтобы пользователь вычислял результат и вводил его в специальное поле.
В большинстве случаев стандартные анализаторы капчи подставят вместо суммы и разности распознанный текст, что будет некорректным результатом.
Ну а если под эту капчу напишут своего бота, то вас уже ничего не спасет.
Выполнение
Сказано - сделано.Недолго думая, я создал в студии новый сборочный проект (чувство хорошего тона подсказывало мне оформить капчу для одного-единственного проекта как отдельную dll и, как оказалось, не зря).
В нем я создал класс с обычным методом расширения для класса HtmlHelper. Тогда весь проект так и назывался — SimpleMvcCaptcha. Суть реализации такова.
Помощник случайным образом генерирует два номера операндов и одну операцию (пока только + или -).
На основе этих параметров рассчитывается результат. Затем происходят два финта ушами.
Сначала нам нужно создать изображение с выражением капчи.
Однако это невозможно сделать внутри помощника.
Поэтому нам необходимо создать тег img, источником изображения для которого будет специально подготовленное действие специального контроллера, которое описано ниже.
Вторая хитрость заключается в том, что нам нужно как-то сохранить информацию о результате, чтобы при последующей публикации результатов на сервер нам не пришлось заниматься распознаванием собственной капчи.
Сначала я хотел пойти немного нестандартным путем из-за отсутствия богатого опыта.
Дело в том, что большинство капч, о которых я читал, передавали свои значения через кеш или сессию.
Мне эта идея не очень понравилась, поэтому я решил сохранить результат операции внутри html самой страницы капчи в скрытом поле.
Но чтобы не облегчать жизнь анализаторам, я решил зашифровать эту строку с помощью AES. Однако вскоре они помогли мне понять, что в этом случае боту будет легко заменить и хэш изображения, и результат для него, что моментально уничтожит персистентность.
Поэтому я все равно пошел по пути большинства.
В сеансе сохраняется небольшой объект, содержащий текст выражения для изображения и текст результата.
Затем этот объект извлекается в двух случаях: при создании изображения и при проверке ввода пользователя.
Теперь о контроллере./// <summary> /// Captcha object /// </summary> internal class Captcha { /// <summary> /// Result of captcha's expression /// </summary> public string Result { get; internal set; } /// <summary> /// Captcha's expression /// </summary> public string Expresion { get; internal set; } }
В примерах, которые я нашел, генерация изображений была оставлена на усмотрение специальных процессоров, таких как .
axd, .
ashx. Я решил, что пусть с этим справится обычный контроллер и экшен.
Вот у меня есть сомнения в правильности решения, поэтому жду критики и конструктивных комментариев по этому поводу.
public class CaptchaController : Controller
{
public FileContentResult GetImage(string id)
{
return File(CaptchaUtils.GetImage(id), "image/gif");
}
}
Проверка также довольно проста: /// <summary>
/// Validates input
/// </summary>
/// <returns>true - validation succeeded \nfalse - validation failed</returns>
public static bool Validate()
{
var ctx = HttpContext.Current;
var captchaAnswer = ctx.Request.Form["captchaAnswer"];
var captchaHidden = ctx.Request.Form["captchaId"];
// If input is not empty
if(!String.IsNullOrEmpty(captchaAnswer) && !String.IsNullOrEmpty(captchaHidden))
{
var captcha = ctx.Session[captchaHidden] as Captcha;
ctx.Session.Remove(captchaHidden);
return captcha != null && captchaAnswer == captcha.Result;
}
return false;
}
Что случилось
Вот так выглядят примеры использования капчи.
Как видите, хелпер генерирует изображение с текстом арифметического выражения (со случайным цветом), также случайным образом заменяет оператор + и - на текст (можно задать в параметрах), а также предоставляет поле для ввода Ответ. Все так же, как и у всех, поэтому удобно пользоваться из коробки.
Клиентский код выглядит следующим образом: <div class="smc-captcha">
<img src='/Captcha/GetImage/08a75516-f1ed-41ca-a926-724a268f171e' alt='капча' class='smc-img-captcha' ><br/>
<input type='hidden' name='captchaId' value='08a75516-f1ed-41ca-a926-724a268f171e' />
<input type='text' name='captchaAnswer' class='smc-input-result' />
</div>
Кастомизация
Большинство параметров, используемых в процессе создания капчи, можно переопределить через файл web.config вашего проекта ASP.NET MVC. К этим параметрам относятся ширина и высота изображения, размер и тип шрифта, текст замены + и - (на картинке выше это третий кадр), максимальное число для использования в выражениях, имя контроллера и действие для отображение изображения.Вы также можете настроить свойства CSS элементов div, img и input, переопределив соответствующие классы.
Открытый источник
Теперь почему я решил написать на Хабре.В заголовке этой статьи упоминается Open Source. Да, после того как я реализовал эту капчу для себя, я решил, что было бы неплохо поделиться ею с остальным сообществом.
Это мой первый опыт разработки с открытым исходным кодом, поэтому мне стало вдвойне интересно.
Весь код, описание и документация размещены на CodePlex по адресу http://simplemvccaptcha.codeplex.com/ под лицензией GPLv2. Заходите, скачивайте, пользуйтесь.
Окончательно
Я очень надеюсь, что этот небольшой проект поможет вам при создании сайтов на базе ASP.NET MVC 3, где потребуется функционал простой капчи, которая легко распознается человеком, но поможет защититься от любых ботов.P.S. А проект, для которого это изначально было написано и о котором я говорил вначале, называется «Факты о программировании» .
Фактов пока не так много, но надеюсь, что с вашей поддержкой проект будет активно развиваться! Пример использования капчи можно найти по адресу страница для добавления своего факта .
Убедительно просим, если вы заметили ошибку в капче или на сайте, не пытайтесь сразу ее сломать.
Лучше дайте мне знать и я исправлю.
Давайте будем конструктивными.
Теги: #C++ #CAPTCHA #asp.net mvc #asp.net mvc 3 #с открытым исходным кодом #bicycle #ASP #ASP
-
Обзор Ноутбука Sony Vaio Vpcs11X9E/B
19 Oct, 24 -
Добавить Подписчиков В Твиттере
19 Oct, 24 -
Награждение Системного Администратора
19 Oct, 24 -
Общие Mobile Dst 01 От Life:) Недостатки
19 Oct, 24 -
Твиттер-Трансляция Russian Techtour 2009
19 Oct, 24