Создание и Внедрение CAPTCHA на PHP: Простая Защита Сайта от Ботов
- Показывать справа: 0
В современной веб-разработке, особенно при создании форм обратной связи, регистраций или комментариев, защита от автоматизированных ботов является критически важным аспектом безопасности. CAPTCHA — это основной инструмент для отделения реальных пользователей от вредоносных скриптов. В этой статье мы подробно рассмотрим, как создать простую, но функциональную CAPTCHA на PHP и интегрировать ее на ваш сайт, обеспечив надежную защиту форм.
В этой статье разберем полный цикл создания CAPTCHA: от генерации случайных примеров на стороне сервера (PHP) до отображения изображения и возможности его обновления на стороне клиента (HTML и JavaScript). Предоставлю готовые к использованию фрагменты кода, которые вы сможете легко интегрировать в свой проект.
Зачем нужна CAPTCHA?
CAPTCHA выполняет несколько ключевых функций:
- Предотвращение спама: Защищает формы комментариев, подписок и обратной связи от автоматической рассылки спама.
- Защита от перегрузки: Снижает нагрузку на сервер, предотвращая создание большого количества фейковых аккаунтов или запросов.
- Улучшение пользовательского опыта (в некоторых случаях): Правильно реализованная CAPTCHA не сильно усложняет процесс для обычного пользователя, но значительно усложняет его для ботов.
Создание CAPTCHA на PHP: Основы
Основная идея серверной части заключается в генерации уникального набора символов, создании из них изображения и сохранении этого набора в сессии пользователя. Затем, при отправке формы, мы сравниваем введенный пользователем текст с тем, что хранится в сессии.
PHP-код для генерации CAPTCHA
Этот скрипт (предполагается, что он находится в файле, например, `create_captcha.php` или обрабатывается через маршрутизацию вашего фреймворка) будет генерировать изображение CAPTCHA. Данный пример я делал на joomla. Код создает картинку где виден математический простой пример. captcha_id - нужен для разных капч на одной странице
<?php
use Joomla\CMS\Factory;
$session = Factory::getSession();
$rand1 = rand(1,9);
$rand2 = rand(1,9);
$captcha_id = $app->input->getVar('captcha_id');
$session->set('captcha_tayoma_form_primer'.$captcha_id,"{$rand1} + {$rand2} = ?");
$session->set('captcha_tayoma_form_otwet'.$captcha_id,($rand1+$rand2));
// 1. Настройки картинки
$imageWidth = 200; // Ширина картинки
$imageHeight = 50; // Высота картинки
// 2. Создание нового изображения (должно быть ДО использования $image)
$image = imagecreatetruecolor($imageWidth, $imageHeight);
// 3. Определение цветов
$backgroundColor = imagecolorallocate($image, 255, 255, 255); // Белый фон (RGB)
$textColor = imagecolorallocate($image, 50, 50, 50); // Темно-серый цвет для текста
// 4. Заливка фона
imagefill($image, 0, 0, $backgroundColor);
// 6. Формирование строки для отображения
$equation = "{$rand1} + {$rand2} = ?";
// 7. Путь к файлу шрифта (используем JPATH_SITE)
$path = JPATH_SITE."/components/com_toytransit/storage/arial.ttf"; // Убедитесь, что этот путь верен!
// 8. Размер и стиль шрифта
$fontSize = 30; // Размер шрифта (можно настроить)
$fontAngle = 0; // Угол поворота текста
// 9. Добавление текста на изображение
// Проверяем, существует ли файл шрифта
if (file_exists($path)) {
// Получаем границы текста для центрирования
// imagettfbbox возвращает массив с координатами: [0] - левый нижний x, [1] - левый нижний y, [2] - правый нижний x, [3] - правый нижний y, [4] - верхний левый x, [5] - верхний левый y, [6] - верхний правый x, [7] - верхний правый y
$textBoundingBox = imagettfbbox($fontSize, $fontAngle, $path, $equation);
// Вычисляем ширину и высоту текста
$textWidth = $textBoundingBox[2] - $textBoundingBox[0]; // правый нижний x - левый нижний x
$textHeight = abs($textBoundingBox[7] - $textBoundingBox[1]); // abs(верхний правый y - левый нижний y)
// Вычисляем позицию X и Y для центрирования текста
$textX = ($imageWidth - $textWidth) / 2;
$textY = ($imageHeight + $textHeight) / 2; // Для центрирования по вертикали с TTF, используется верхний край текста (y-координата)
// Рисуем текст
imagettftext($image, $fontSize, $fontAngle, $textX, $textY, $textColor, $path, $equation);
} else {
// Если файл шрифта не найден, выводим сообщение об ошибке или используем предустановленный шрифт
// Для простоты, здесь мы добавим текст с сообщением об ошибке
$errorMessage = "Шрифт не найден!";
$errorFontSize = 16;
$errorTextWidth = imagefontwidth($errorFontSize) * strlen($errorMessage);
$errorTextHeight = imagefontheight($errorFontSize);
$errorX = ($imageWidth - $errorTextWidth) / 2;
$errorY = ($imageHeight - $errorTextHeight) / 2;
imagestring($image, $errorFontSize, $errorX, $errorY, $errorMessage, $textColor);
// Либо можно попробовать использовать предустановленный шрифт, если он доступен
// imagestring($image, 5, 50, 70, "Шрифт не найден!", $textColor);
}
// 10. Вывод картинки в браузер
header('Content-Type: image/png'); // Указываем тип содержимого
imagepng($image); // Выводим картинку в формате PNG
// 11. Освобождение памяти
imagedestroy($image);
exit;
Важно:
- Не забудьте установить расширение GD для PHP (`php_gd2` в `php.ini`).
- Укажите правильный путь к файлу шрифта `.ttf`. Если шрифта нет, код будет использовать стандартные шрифты GD, но это может выглядеть менее привлекательно.
Внедрение CAPTCHA в HTML-форму
Для отображения CAPTCHA в вашей HTML-форме используйте тег `` с ссылкой на PHP-скрипт генерации. Также добавьте поле ввода для пользователя.
HTML-вставки в форму
<div class="uk-captcha-question uk-margin">
<img
class="captcha-image_form"
src="/index.php?option=com_toytransit&task=ajax&action=create_captcha&captcha_id=yor_id"
/>
<input
name="captcha"
class="uk-input uk-form-width-small"
type="text"
placeholder="Твой ответ"
aria-label="Input"
/>
</div>
<button type="button" class="refresh-captcha-btn">Обновить</button>
</div>
- Атрибут `src` в теге `
` указывает путь к вашему PHP-скрипту, который генерирует изображение. Параметр `captcha_id=form` используется для идентификации, если у вас несколько CAPTCHA.
- Добавлена кнопка "Обновить" для удобства пользователя.
JavaScript для обновления CAPTCHA
Чтобы пользователи могли обновить CAPTCHA, если они не распознали символы, используем JavaScript. Это позволит сгенерировать новое изображение без перезагрузки всей страницы.
JavaScript код для обновления CAPTCHA
// Предполагается, что jQuery уже подключен
jQuery(document).ready(function() {
// Функция для обновления CAPTCHA
function refreshCaptcha() {
var captchaImage = jQuery("#message_form_order").find('.captcha-image_form');
// Формируем новый URL с уникальным параметром (текущее время)
// Это гарантирует, что браузер не будет использовать кэшированную версию.
var newSrc = '/index.php?option=com_toytransit&task=ajax&action=create_captcha&captcha_id=form&_=' + new Date().getTime();
captchaImage.attr('src', newSrc);
// Очищаем поле ввода капчи после обновления изображения
jQuery("#message_form_order").find('[name="captcha"]').val('');
}
// Обработчик клика по кнопке обновления
jQuery("#message_form_order").on('click', '.refresh-captcha-btn', function() {
refreshCaptcha();
});
// Опционально: можно обновлять CAPTCHA при клике на само изображение
jQuery("#message_form_order").on('click', '.captcha-image_form', function() {
refreshCaptcha();
});
});
//Этот код можно вставлять там где отправляется форма и приходит ответ - чтобы капчу переобновить
var captchaImage = jQuery("#message_form_order").find('.captcha-image_form');
// Формируем новый URL с уникальным параметром (текущее время)
// Это гарантирует, что браузер не будет использовать кэшированную версию.
var newSrc = '/index.php?option=com_toytransit&task=ajax&action=create_captcha&captcha_id=form&_=' + new Date().getTime();
captchaImage.attr('src', newSrc);
// Очищаем поле ввода капчи после обновления изображения
jQuery("#message_form_order").find('[name="captcha"]').val('');
- Функция `refreshCaptcha` изменяет атрибут `src` изображения CAPTCHA. Добавление `new Date().getTime()` в URL гарантирует, что браузер не будет использовать кешированную версию изображения.
- Поле ввода CAPTCHA очищается при каждом обновлении.
Проверка CAPTCHA при отправке формы
На стороне сервера (при обработке отправки вашей формы) необходимо проверить введенный пользователем код с тем, что хранится в сессии.
PHP-код для проверки CAPTCHA
<?php
$captcha = $app->input->getVar('captcha');
$session = Factory::getSession();
$yor_id = 'form';
$captcha_tayoma_form_otwetform = $session->get('captcha_tayoma_form_otwet'.$yor_id);
if ( $captcha_tayoma_form_otwetform!=$captcha){
$status = 0;
$error = 'Капча не пройдена';
}
- Мы сравниваем введенный пользователем текст (приведенный к нижнему регистру для регистронезависимости) с кодом из сессии.
- Если коды не совпадают, выводится сообщение об ошибке.
Заключение
Создание и внедрение CAPTCHA на PHP — это эффективный способ повысить безопасность вашего сайта и защитить его от автоматизированных атак. Предоставленные примеры кода на PHP, HTML и JavaScript позволяют легко реализовать эту функциональность. Не забывайте адаптировать пути к файлам, ключи сессий и стили под специфику вашего проекта, чтобы CAPTCHA идеально вписалась в общий дизайн и обеспечивала надежную защиту.