KCAPTCHA для Yii

в 9:07, , рубрики: yii, каптча, метки: ,

Первая проблема которая у меня встала при работе Yii — отсутствие нормальной каптчи. Дефолтная каптча меня не устроила ряду причин:

  • постонянно глючила (просто нажимая F5 иногда она отображалась нормально, иногда отображалась пустая картинка, иногда каринка с одиним первым симоволом);
  • сам агоритм мне показался слишком простым (+ используется всего один шрифт);
  • не обновлялся код на картинке при перезагрузки страницы.

Прогуглив, я понял, что с подобными проблемами сталкиваюсь не я один. А вариант с рекаптчей тоже «не вариант» — её было невозможно вписать в нужный мне дизайн (либо я просто плохо в ней разобрался).

Т.к. в своих проектах я обычно использую каптчу «KCAPTCHA» (http://captcha.ru/kcaptcha/), то решил совместить существующую каптчу из Yii и «KCAPTCHA». И вот, что у меня, получилось — glavweb.ru/public/download/kcaptcha.zip

Использование каптчи

Первым делом загружаем к себе каптчу отсюда glavweb.ru/public/download/kcaptcha.zip.
Далее, распаковать архив необходимо в папку «protected/extensions», вашего Yii приложения. Так что бы у вас получилась структура:
protected/
extensions/
kcaptcha/
fonts/
KCaptchaAction.php

Т.к. расширение содержит только Action, а виджет каптчи и валидатор используются стандартные, описывать полностью подключение каптчи я не буду, это достатчно хорошо сделано в рецептах -http://www.yiiframework.ru/doc/cookbook/ru/form.captcha. Изменения касаются только контроллера, добавляем в него, что-то вроде этого:
public function actions()
{
return array(
'captcha'=>array(
'class' => 'application.extensions.kcaptcha.KСaptchaAction',
'maxLength' => 6,
'minLength' => 5,
'foreColor' => array(mt_rand(0, 100), mt_rand(0, 100),mt_rand(0, 100)),
'backColor' => array(mt_rand(200, 210), mt_rand(210, 220),mt_rand(220, 230))
)
);
}

Возможные параметры каптчи

alphabet — Используемый алфавит. По умолчанию «0123456789abcdefghijklmnopqrstuvwxyz». Не следует менять, не изменяя файлы шрифта.

allowedSymbols — Символы используемые для рисования каптчи, без похожих символов (o => 0, 1 => l, i => j, t => f). По умолчанию «23456789abcdeghkmnpqsuvxyz».

width — Ширина каптчи. По умолчанию равна 120. Не следует менять это без необходимости, эти параметры оптимальны.

height — Высота каптчи. По умолчанию равна 60. Не следует менять это без необходимости, эти параметры оптимальны.

minLength — Минимальное количество символов каптчи. По умолчанию равно 6.

maxLength — Максимальное количество символов каптчи. По умолчанию равно 7.

fluctuationAmplitude — Вертикальная амплитуда колебания символа, разделенная на 2. По умолчанию равно 5.

noSpaces — Запрет пробелов между символами. По умолчанию равно true.

foreColor — Цвет текста каптчи в формате RGB. Принимает значение либо в виде массива либо в виде строки разделенной запятыми.

backColor — Цвет заднего фона каптчи в формате RGB. Принимает значение либо в виде массива либо в виде строки разделенной запятыми.

testLimit — Значение того сколько раз та же каптча, будет отображаться. Этот параметр влияет только на ошибочный ввод капчи. На простой рефреш страницы не влияет. По умолчанию равно 3.

fixedVerifyCode — Фиксированный код проверки. Это в основном используется в автоматизированных тестах, где мы хотим воспроизвести тот же код проверки каждый раз когда запускаем тесты. По умолчанию равен null.

fontsDir — Абсолютный путь до директории с шрифтами. По умолчанию равен null, это значит, что используются шрифты постовляемые вместе с расширением.

Обновление кода картинки после перезагрузки страницы

А вот с обновление кода картинки после перезагрузки страницы всё оказалось немного сложнее. Загвоздка в валидаторе «CCaptchaValidator», вернее в его методе отвечающим за клиентскую часть. Даже если сделать обновление проверочного кода при каждой загрузке каптчи, то в js (генерируемый валидатором) всё равно мы получим код с предыдущей картинки. Это происходит потому, что запрос к картинке идёт после загрузки страницы. Т.е. вначале в js коде мы получаем код картинки сохранённый в сессиях, потом идет запрос в <img>, сессия обновляется и в итоге код с картинки не соответствует соответствующему коду в js (прим. естественно, что в js не сам код картинки, а его хэш).

Выход тут либо переписать валидатор и обновлять проверочный в валидаторе при отображении в js ($captcha->getVerifyCode(true)) либо удалять сессию с кодом в действии которое отвечает за отображнении формы с каптчей:

// Refresh captcha
Yii::import('application.extensions.kcaptcha.KCaptchaAction');
$session = Yii::app()->session;
unset($session[KCaptchaAction::SESSION_KEY]);

Автор: Nilov_A

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js