Интеграция CAPTCHA в форму регистрации WordPress
В этой статье мы создадим плагин, который на этот раз будет интегрировать CAPTCHA (Google reCAPTCHA) с формой регистрации WordPress по умолчанию. Конечно, HTTP API будет использоваться для связи с ReCaptcha для проверки ответа, предоставляемого пользователем на запрос CAPTCHA.
Ниже приведен скриншот формы регистрации, защищенной CAPTCHA для предотвращения спам-регистраций:

Для чего интегрировать CAPTCHA в форму регистрации?
В связи с ростом популярности WordPress сайты, созданные на базе этой CMS, стали легкой мишенью для недобросовестных пользователей, использующих программное обеспечение для автоматизированных регистраций.
Это программное обеспечение сканирует сеть в поисках сайтов, созданных на WordPress, и начинает регистрировать сотни и тысячи аккаунтов каждую минуту.
Когда я только начинал работать с WordPress, я помню, как проснулся однажды утром, а мой почтовый ящик был полон уведомлений о регистрации более пятидесяти учетных записей пользователей.
Одним из проверенных и надежных способов снижения а, возможно, и полного устранения спама, является реализация в веб-формах CAPTCHA.
CAPTCHA - это программа, которая защищает веб-сайты от ботов путем создания и сортировки тестов, которые люди могут пройти, а программы на их нынешнем уровне развития не могут.
Благодаря интеграции CAPTCHA в форму регистрации WordPress, спам-регистрации скоро станут для вас лишь воспоминаниями из прошлого.
Разработка плагина
Прежде чем мы начнем составлять код плагина, давайте зайдем на reCAPTCHA, зарегистрируем ваше доменное имя и возьмем ваши public и private API-ключи.
Во-первых, включаем заголовок плагина:
<?php
/*
Plugin Name: reCAPTCHA in WP Registration Form
Plugin URI: http://sitepoint.com
Description: Add Google's reCAPTCHA to WordPress registration form
Version: 1.0
Author: Agbonghama Collins
Author URI: http://w3guy.com
License: GPL2
*/
Создаем класс PHP с двумя свойствами, в которых будут храниться ваши приватный и публичный ключи:
class Captcha_Registration_Form {
/** @type string private key|public key */
private $public_key, $private_key;
Метод конструктора плагина будет состоять из двух обращений действий, которые будут добавлять вопросы CAPTCHA в форму регистрации и проверять ответы на них:
/** конструктор класса */
public function __construct() {
$this->public_key = '6Le6d-USAAAAAFuYXiezgJh6rDaQFPKFEi84yfMc';
$this->private_key = '6Le6d-USAAAAAKvV-30YdZbdl4DVmg_geKyUxF6b';
// добавляет captcha в форму регистрации
add_action( 'register_form', array( $this, 'captcha_display' ) );
// аутентифицирует ответ captcha
add_action( 'registration_errors', array( $this, 'validate_captcha_field' ), 10, 3 );
}
Метод captcha_display(), который будет выводить reCAPTCHA, добавляется в форму регистрации WordPress через действие register_form.
Метод validate_captcha_field(), который проверяет, что: поле CAPTCHA заполнено, а также проверяет ответ, предоставленный пользователем, - добавляется в систему проверки регистрации действием registration_errors.
Ниже приведен код методов captcha_display() и validate_captcha_field(), о которых я только что рассказал:
/** Вывод поля формы reCAPTCHA. */
public function captcha_display() {
?>
<script type="text/javascript"
src="http://www.google.com/recaptcha/api/challenge?k=<?=$this->public_key;?>">
</script>
<noscript>
<iframe src="http://www.google.com/recaptcha/api/noscript?k=<?=$this->public_key;?>"
height="300" width="300" frameborder="0"></iframe>
<br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40">
</textarea>
<input type="hidden" name="recaptcha_response_field"
value="manual_challenge">
</noscript>
<?php
}
/**
* Проверка ответа captcha
*
* @param $user строка имя пользователя
* @param $password строка пароль
*
* @return WP_Error|WP_user
*/
public function validate_captcha_field($errors, $sanitized_user_login, $user_email) {
if ( ! isset( $_POST['recaptcha_response_field'] ) || empty( $_POST['recaptcha_response_field'] ) ) {
$errors->add( 'empty_captcha', '<strong>ERROR</strong>: CAPTCHA should not be empty');
}
if( $this->recaptcha_response() == 'false' ) {
$errors->add( 'invalid_captcha', '<strong>ERROR</strong>: CAPTCHA response was incorrect');
}
return $errors;
}
Обратите внимание на validate_captcha_field(), особенно на второй оператор условия if, вызов осуществляется для recaptcha_response(), чтобы проверить правилен ли ответ, предоставленный пользователем (возвращается false, если ответ неверный).
Давайте рассмотрим код и пояснения к нему для recaptcha_response():
/**
* Получаем ответ reCAPTCHA API.
*
* @return string
*/
public function recaptcha_response() {
// Данные вопроса reCAPTCHA
$challenge = isset($_POST['recaptcha_challenge_field']) ? esc_attr($_POST['recaptcha_challenge_field']) : '';
// Данные ответа reCAPTCHA
$response = isset($_POST['recaptcha_response_field']) ? esc_attr($_POST['recaptcha_response_field']) : '';
$remote_ip = $_SERVER["REMOTE_ADDR"];
$post_body = array(
'privatekey' => $this->private_key,
'remoteip' => $remote_ip,
'challenge' => $challenge,
'response' => $response
);
return $this->recaptcha_post_request( $post_body );
}
Пояснение кода: Чтобы убедиться, что ответ CAPTCHA, предоставленный пользователем является правильным, отправляется POST-запрос к конечной точке http://www.google.com/recaptcha/api/verify со следующими параметрами:
- privatekey - ваш секретный ключ;
- remoteip - IP-адрес пользователя, который отвечал на вопрос CAPTCHA;
- challenge - значение recaptcha_challenge_field, переданное через форму;
- response - значение recaptcha_response_field, переданное через форму.
Во-первых, POST-данные вопроса и ответа, отправленные через форму, захватываются и сохраняется в $challenge и $response соответственно.
IP-адрес пользователя захватывается через $_SERVER["REMOTE_ADDR"] и сохраняется в $remote_ip.
Для отправки POST-запроса с HTTP API, параметры или тело должны быть представлены в виде массива, как это показано ниже:
$post_body = array(
'privatekey' => $this->private_key,
'remoteip' => $remote_ip,
'challenge' => $challenge,
'response' => $response
);
Параметры POST передаются в качестве аргумента к recaptcha_post_request (), который затем отправляет запрос с параметрами по адресу https://www.google.com/recaptcha/api/verify и возвращает ответ API.
recaptcha_post_request() возвращает true, если ответ на вопрос CAPTCHA верен, в противном случае - false.
Ниже приводится код recaptcha_post_request():
/**
* Отправка запроса HTTP POST и возвращение результата.
*
* @param $post_body массив тела HTTP POST
*
* @return bool
*/
public function recaptcha_post_request( $post_body ) {
$args = array( 'body' => $post_body );
// отправляем POST-запрос к Google reCaptcha Server
$request = wp_remote_post( 'https://www.google.com/recaptcha/api/verify', $args );
// получаем тело ответа на запрос
$response_body = wp_remote_retrieve_body( $request );
/**
* разбиваем тело ответа и используем request_status
* @see https://developers.google.com/recaptcha/docs/verify
*/
$answers = explode( "n", $response_body );
$request_status = trim( $answers[0] );
return $request_status;
}
Пояснение кода: массив $args с телом POST $post_body сохраняется в созданный ключ body.
wp_remote_post отправляет POST-запрос с ответом, сохраняемым в $request.
Тело ответа извлекается через wp_remote_retrieve_body и сохраняется в $response_body.
Если проверка CAPTCHA была пройдена, reCAPTCHA API возвращает:
true
success
В противном случае возвращается следующая ошибка:
false
incorrect-captcha-sol
Чтобы метод recaptcha_post_request возвращал логическое значение (true в случае успешного прохождения проверки и false, если наоборот); ответ $response_body разбивается, и данные массива с индексами 0 обрезаются, чтобы удалить лишние пробелы в начале и в конце строк.
В конце мы закрываем класс плагина:
} // Captcha_Registration_Form
Чтобы привести класс в действие, нам нужно установить его следующим образом:
new reCAPTCHA_Login_Form();
Заключение
Если вы хотите использовать этот плагин на своем WordPress сайте или изучить его код, скачайте плагин из хранилища на GitHub.
Успехов в работе!