Как добавить Yandex SmartCaptcha в форму логина и регистрации
Чтобы защитить форму логина и регистрации на вашем сайте с помощью яндекс капчи, нужно сначала создать и настроить её в консоли yandex.cloud, чтобы получить ключи

Затем нужно добавить такой код в плагин ProFunctions и вставить ключи капчи вместо строк Ключ_клиента и Ключ_сервера
class CustomYandexSmartCaptcha {
protected $site_key;
protected $secret_key;
/**
* @param string $site_key
* @param string $secret_key
*/
public function __construct( $site_key, $secret_key ) {
$this->site_key = $site_key;
$this->secret_key = $secret_key;
}
public function init() {
add_action( 'wp_enqueue_scripts', [ $this, '_enqueue_scripts' ] );
add_action( 'woocommerce_login_form', [ $this, '_output_captcha' ] );
add_action( 'woocommerce_register_form', [ $this, '_output_captcha' ] );
add_filter( 'woocommerce_process_login_errors', [ $this, '_validate_captcha' ] );
add_filter( 'woocommerce_registration_errors', [ $this, '_validate_captcha' ] );
}
public function _enqueue_scripts() {
if ( is_account_page() ) {
wp_enqueue_script(
'yandex-smartcaptcha',
'https://smartcaptcha.cloud.yandex.ru/captcha.js',
[],
null,
true
);
}
}
public function _output_captcha() {
?>
<div
class="smart-captcha"
data-sitekey="<?php echo esc_attr( $this->site_key ) ?>">
</div>
<?php
}
public function _validate_captcha( $validation_error ) {
$token = $_POST['smart-token'] ?? '';
if ( empty( $token ) ) {
$validation_error->add(
'captcha',
__( 'Подтвердите, что вы не робот.', 'textdomain' )
);
return $validation_error;
}
if ( ! $this->validate( $token ) ) {
$validation_error->add(
'captcha',
'Не удалось пройти проверку на робота'
);
}
return $validation_error;
}
protected function validate( $token ) {
$response = wp_remote_post(
'https://smartcaptcha.yandexcloud.net/validate',
[
'body' => [
'secret' => $this->secret_key,
'token' => $token,
'ip' => $_SERVER['REMOTE_ADDR'],
],
]
);
$data = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $data['status'] ) || $data['status'] !== 'ok' ) {
return false;
}
return true;
}
}
( new CustomYandexSmartCaptcha(
'Ключ_клиента',
'Ключ_сервера'
) )->init();
Если необходимо добавить капчу на формы логина в админку, формы комментариев и отзывов, то нужно использовать более универсальный класс:
class CustomYandexSmartCaptcha {
protected $site_key;
protected $secret_key;
protected $check_result = null;
public function __construct( $site_key, $secret_key ) {
$this->site_key = $site_key;
$this->secret_key = $secret_key;
}
public function init() {
// фронтенд
add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
// wp-login.php
add_action( 'login_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
/*
* WooCommerce
*/
add_action( 'woocommerce_login_form', [ $this, 'output_captcha' ] );
add_action( 'woocommerce_register_form', [ $this, 'output_captcha' ] );
add_action( 'woocommerce_lostpassword_form', [ $this, 'output_captcha' ] );
add_filter( 'woocommerce_process_login_errors', [ $this, 'validate_wc_login' ] );
add_filter( 'woocommerce_registration_errors', [ $this, 'validate_wc_registration' ] );
add_action( 'lostpassword_post', [ $this, 'validate_lost_password' ] );
/*
* WordPress login
*/
add_action( 'login_form', [ $this, 'output_captcha' ] );
add_filter( 'authenticate', [ $this, 'validate_wp_login' ], 30, 3 );
/*
* WordPress register
*/
add_action( 'register_form', [ $this, 'output_captcha' ] );
add_filter( 'registration_errors', [ $this, 'validate_wp_registration' ], 10, 3 );
/*
* Comments / Woo reviews
*/
add_action( 'comment_form_after_fields', [ $this, 'output_captcha' ] );
add_action( 'comment_form_logged_in_after', [ $this, 'output_captcha' ] );
add_filter( 'preprocess_comment', [ $this, 'validate_comment' ] );
}
public function enqueue_scripts() {
wp_enqueue_script(
'yandex-smartcaptcha',
'https://smartcaptcha.cloud.yandex.ru/captcha.js',
[],
null,
true
);
}
public function output_captcha() {
?>
<div
class="smart-captcha"
style="min-width: unset;margin-bottom: 1rem"
data-sitekey="<?php echo esc_attr( $this->site_key ); ?>">
</div>
<?php
}
/**
* Общая проверка
*/
protected function check(): bool {
if ( null !== $this->check_result ) {
return $this->check_result;
}
$token = sanitize_text_field(
$_POST['smart-token'] ?? ''
);
if ( empty( $token ) ) {
$this->check_result = false;
return $this->check_result;
}
$this->check_result = $this->validate( $token );
return $this->check_result;
}
protected function is_wp_register_request(): bool {
return isset( $_POST['wp-submit'] )
&& 'registration' === ( $_REQUEST['action'] ?? '' );
}
protected function is_comment_request(): bool {
return ! empty( $_POST['comment_post_ID'] )
&& isset( $_POST['comment'] );
}
/*
* WooCommerce
*/
public function validate_wc_login( $errors ) {
if ( ! $this->check() ) {
$errors->add(
'captcha',
__( 'Подтвердите, что вы не робот.', 'textdomain' )
);
}
return $errors;
}
public function validate_wc_registration( $errors ) {
if ( ! $this->check() ) {
$errors->add(
'captcha',
__( 'Подтвердите, что вы не робот.', 'textdomain' )
);
}
return $errors;
}
public function validate_lost_password( $errors ) {
if ( ! $this->check() ) {
$errors->add(
'captcha',
__( 'Подтвердите, что вы не робот.', 'textdomain' )
);
}
}
/*
* WP login
*/
public function validate_wp_login(
$user,
$username,
$password
) {
if ( is_wp_error( $user ) ) {
return $user;
}
if ( ! $this->check() ) {
return new WP_Error(
'captcha',
__( 'Подтвердите, что вы не робот.', 'textdomain' )
);
}
return $user;
}
/*
* WP register
*/
public function validate_wp_registration(
$errors
) {
if ( ! $this->is_wp_register_request() ) {
return $errors;
}
if ( ! $this->check() ) {
$errors->add(
'captcha',
__( 'Подтвердите, что вы не робот.', 'textdomain' )
);
}
return $errors;
}
/*
* Comments
*/
public function validate_comment(
$commentdata
) {
if ( ! $this->is_comment_request() ) {
return $commentdata;
}
if ( ! $this->check() ) {
wp_die(
esc_html__(
'Подтвердите, что вы не робот.',
'textdomain'
)
);
}
return $commentdata;
}
/*
* API
*/
protected function validate( $token ): bool {
$response = wp_remote_post(
'https://smartcaptcha.yandexcloud.net/validate',
[
'timeout' => 10,
'body' => [
'secret' => $this->secret_key,
'token' => $token,
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
],
]
);
if ( is_wp_error( $response ) ) {
return false;
}
$data = json_decode(
wp_remote_retrieve_body( $response ),
true
);
return ! empty( $data['status'] )
&& $data['status'] === 'ok';
}
}
Вам помог ответ?