Капча для входа в WordPress

В сегодняшнем уроке мы будем писать плагин reCAPTCHA, который интегрируется в систему WordPress, используя логин сервиса Google reCAPTCHA. Поэтому для плагина капчи входа в систему WordPress мы применим HTTP API.

Что такое капча и как создать плагин для WordPress в этом уроке Я рассматривать не буду, об этом Вы можете узнать на странице Создать плагин для WordPress. Плагинов с помощью HTTP API довольно много, в нашем случае HTTP API будет использоваться для отправки запроса POST reCAPTCHA и проверки ответа пользователем на вызов капчи.

Если Вам нужна капча для другой системы, рекомендую прочитать статью Капча на PHP.

Смотрите снимок, как будет выглядеть по умолчанию форма входа в WordPress разработанная в течение этого урока.

Вид по умолчанию формы входа в WordPress разработанная в течение этого урока
Вид по умолчанию формы входа в WordPress

Разработка плагина CAPTCHA

Прежде чем начать интегрировать плагин в WordPress, нужно на главной странице сервиса reCAPTCHA, зарегистрировать доменное имя и скачать ключи API. Сервис Google reCAPTCHA предлагает скачать ключи API в формате CSV, где общий и секретный ключ разделены двоеточием. Ключ API понадобится нам дальше для подключения капчи.

Сервис Google reCAPTCHA предлагает скачать ключи API в формате CSV
Скачать ключи API в формате CSV

Дальше для плагина создаём страницу recaptcha-wp-login-form.php и вставляем заголовок:

<?php
/*
Название плагина: Капча для входа в WordPress
Описание: добавить Google reCAPTCHA для входа в WordPress
Версия: 1.0
Автор: Agbonghama Collins
Лицензия: GPL2
*/ ?>

Теперь необходимо добавить ключ API в созданный класс php с двумя свойствами, которые будут хранить общий и секретный ключ сервиса reCAPTCHA.

class reCAPTCHA_Login_Form {

/** строка ключей */
private $public_key, $private_key;

/** конструктор */
public function __construct() {
$this->public_key = 'Сюда вставляем общий ключ';
$this->private_key = 'Здесь вставляем секретный ключ';

// добавляет капчи для формы входа в WP
add_action( 'login_form', array( $this, 'captcha_display' ) );

// валидность ответа капчи
add_action( 'wp_authenticate_user', array( $this, 'validate_captcha_field' ), 10, 2 );
}

Пояснение кода:
Ключи reCAPTCHA public и private сохраняются в свойствах класса php.

Метод captcha_display() выводит reCAPTCHA для формы входа в WordPress.

Метод validate_captcha_field() проверит: пустое поле ввода или нет, валидный ответ или нет.

Ниже приведен код для 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
} ?>

/**
* Валидность ответа капчи
*
* $user - логин пользователя
* $password - пароль для входа
*
* WP_Error|WP_user
*/
public function validate_captcha_field($user, $password) {

if ( ! isset( $_POST['recaptcha_response_field'] ) || empty( $_POST['recaptcha_response_field'] ) ) {
return new WP_Error( 'empty_captcha', 'Поле не должно быть пустым');
}

if( isset( $_POST['recaptcha_response_field'] ) && $this->recaptcha_response() == 'false' ) {
return new WP_Error( 'invalid_captcha', 'Неправильный ответ');
}

return $user;
}

Смотрите на validate_captcha_field() именно второй условный оператор if вызывает метод recaptcha_response() для проверки правильности ответа ( т.е. возвращает false, если ответ капчи неправильный).

Давайте разберём код recaptcha_response().

/**
* Получить ответ reCAPTCHA API
*/
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 );

}

Пояснение кода
Проверить правильность ответа капчи предоставленный пользователем, POST-запрос необходимо отправить по адресу http://www.google.com/recaptcha/api/verify со следующими параметрами:

  • privatekey Ваш секретный ключ
  • remoteip IP-адрес пользователя, который заполнил капчу.
  • 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 если ответ капча правильный, false если ответ не правильный.

Ниже приведен код для recaptcha_post_request()

/**
* Отправить HTTP POST-запрос и вернуть ответ.
*
* @param массив $post_body тело POST HTTP
*
* @return bool
*/
public function recaptcha_post_request( $post_body ) {

$args = array( 'body' => $post_body );

// сделать POST-запрос к серверу Google reCaptcha
$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_body для создания и сохранения ключа в тело.

wp_remote_post отправить POST-запрос с ответом и сохранит в $request.

Тело извлекает wp_remote_retrieve_body и сохраняет в $response_body.

Если тест captcha был принят, сервис reCAPTCHA API возвращает:

true
success

Если тест captcha не принят, возвращается сообщение об ошибке:

false
incorrect-captcha-sol

Чтобы получить метод recaptcha_post_request с логическим значением true и false; ответ $response_body это exploded и данные массива с индексом 0, trimmed, чтобы удалить все лишние пробелы в начале и в конце строки.

Наконец, мы закрываем класс плагина.

} // reCAPTCHA_Login_Formp

Что бы заставить класс работать, в конце нужно добавить:

new reCAPTCHA_Login_Form();

И последнее, в плагин reCAPTCHA мной добавлена функция для выравнивания блока с капчей по размеру окна формы входа в WordPress.

function recaptcha_login_css() {
echo '<style>.login form{width: 100%;}#recaptcha_widget_div{margin-bottom: 24px;}</style>';
}

add_action('login_head', 'recaptcha_login_css');
к меню ↑

Заключение

Если вы хотите использовать плагин reCAPTCHA на своём сайте WordPress или изучать код, скачайте бесплатно полностью код.

Скачать плагин reCAPTCHA