Colocar Captcha en login y registro de WordPress (Sin Plugins)

Colocar ReCAPTCHA en login y registro de WordPress

Si nos preocupa la seguridad de nuestra web, uno de los pasos indispensables a realizar es la inserción de un Captcha en el formulario de acceso, y si contamos con capacidad de registro también en este formulario.

Qué es Captcha

Los captcha son una serie de pruebas que sirven para verificar que el usuario que rellena un formulario es humano y no un robot. En internet existe un gran número de Bots que se dedican a analizar las webs, algunos por motivos benignos y otros malignos. Estos últimos pueden encontrar un punto de acceso a nuestra web e insertar código malicioso.

Existe una gran variedad de Captchas como:

  • Basados en texto distorsionado
  • Basados en cálculos matemáticos
  • Basados en juegos de palabras
  • Basados en preguntas de historia general o preguntas lógicas
  • Basados en audio
  • Etc

Qué es un Recaptcha

Recaptcha es la tecnología Captcha creada por Google. Cuenta con 3 versiones con algunas variaciones. Hay quién prefiere Recaptcha v2 ya que está formado por una serie de verificaciones mediante imágenes o verificación haciendo clic en una checkbox. Y hay quien pefiere Recaptcha v3 ya que es menos invasivo para el usuario, aunque sí que suele tener un mayor impacto en cuanto a velocidad de carga.

Yo personalmente prefiero la versión 2, así que explicaré cómo crear un Recaptcha v2 con nuestra cuenta de Google y para colocarlo en nuestros formularios de registro y de login de nuestro WordPress.

Más abajo, también añadiré un pequeño texto explicando cómo hacer lo mismo con un ReCAPTCHA v3.

Creación de ReCAPTCHA

Crear un Recaptcha v2 para nuestro WordPress

WordPress es la tecnología más usada del mundo para el desarrollo web. Esto nos garantiza que se mantendrá viva por muchísimo tiempo pero también tiene su lado negativo: es de las tecnologías más atacadas por malware. Esto es por estadística, ya que WordPress es muy robusto en cuanto a seguridad. A pesar de ello, existen algunas técnicas que pueden aportar una capa más de protección, como añadir un Captcha en el formulario de login, así evitaremos muchos ataques por parte de bots malintencionados.

Explicamos cómo crear un Recaptcha v2 para luego utilizar en nuestra página de WordPress:

  1. Para empezar tendremos que acceder o crear nuestro panel de control en esta página de Google. Si no tenemos cuenta nos llevará directamente a la página de creación.
  2. En el campo Etiqueta pondremos un nombre para identificar el proyecto. Por ejemplo: mi web en WordPress
  3. En tipo de reCAPTCHA seleccionamos la versión que queramos utilizar. En este caso reCAPTCHA v2
  4. En Dominios añadiremos nuestro dominio sin prefijo. Por ejemplo: midominio.com
  5. En Propietarios debe aparecer nuestro mail. Además podremos añadir otros mails si queremos que otra persona tenga acceso
  6. Tendremos que activar la pestaña Acepta las condiciones del Servicio de reCAPTCHA
  7. La pestaña “Enviar alertas a los propietarios” nos permitirá recibir mails con accesos sospechosos o problemas en la configuración 
  8. Hacemos clic en ENVIAR y nos llevará a una página donde tendremos la “clave del sitio web” o “clave pública” y la “clave_secreta”
    Para este tutorial nuestras claves serán:
    1. Clave pública: CLAVE_PUBLICA
    2. Clave secreta: CLAVE_SECRETA
Claves de ReCAPTCHA

Insertar Recaptcha en WordPress para novatos (PLUGINS)

Aunque no lo recomiendo por muchos motivos, podremos usar algún plugin para la implementación del recaptcha en nuestro formulario de acceso a WordPress. Entre ellos encontramos:

  • Login No Captcha Recaptcha
  • Advanced Google reCAPTCHA
  • Login Security reCAPTCHA
  • UsersWP – ReCaptcha

Insertar Recaptcha en WordPress login y registro de WordPress para usuarios avanzados (Recomendado)

Es sorprendente que no existan tutoriales sobre esto en internet. Así que bueno, os lo comparto y espero que sea útil.

Aquí llega la chicha, lo bueno, el picar código. Para implementar esta funcionalidad usaremos un total de 2 hooks y 3 filtros:

  1. Hook login_form: Lo usaremos para el formulario de acceso o login. Con él podremos insertar el div donde se cargará el ReCaptcha, además de la llamada a la API de Google
  2. Hook register_form: Básicamente lo mismo que el hook anterior, solo que para el formulario de registro
  3. Filter login_errors: Con este filtro llamaremos a la global de errores y añadiremos los nuevos errores posibles al usar de forma incorrecta nuestro ReCAPTCHA o no haber aceptado la política de privacidad
  4. Filter wp_authenticate_user: Este filtro es el que incluye WordPress donde se verifica el usuario. Añadiremos un nuevo código para verificar la respuesta de la API ReCAPTCHA por parte de Google
  5. Filter registration_errors: Es el filtro desde el que añadiremos los nuevos errores así como la gestión la manipulación de datos recibida por parte del ReCAPTCHA en el formulario de registro

Debemos tener en cuenta que hemos usado CLAVE_PÚBLICA y CLAVE_PRIVADA. Es importante que la sustituyamos por las claves recibidas en la creación del ReCAPTCHA.

Añadir aceptación de política de privacidad en el formulario de registro de WordPress

Como veréis en el código también he añadido una casilla de verificación para aceptar obligatoriamente la política de privacidad en el registro de WordPress. Así, si queremos tener una membresía podremos utilizar la que viene por defecto con nuestro WordPress.

Código para ReCAPTCHA en login y registro

Añadimos div donde se cargará el Recaptcha así como el script desde donde se carga la API de Google:

function webheroe_login_recaptcha() {
 ?>
    <div style="margin-bottom:10px;" class="g-recaptcha" data-sitekey="CLAVE_PÚBLICA"></div>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    <?php
}
add_action( 'login_form', 'webheroe_login_recaptcha' );

Verificamos usuario en el login, así como la correcta cumplimentación del ReCAPTCHA. Además se añaden nuevos errores pertenecientes al mal uso del CAPTCHA.

function webheroe_verifica_recaptcha($user, $password){
 if(isset($_POST['g-recaptcha-response'])){
    $response = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=CLAVE_SECRETA&response=' . $_POST['g-recaptcha-response'] );
    $response = json_decode($response['body'], true);
    if($response['success'] == true){
        return $user;
    }else{
        return new WP_Error( 'recaptcha_mal', 'Recaptcha no completado' );
    }
 }else{
    return new WP_Error( 'recaptcha_error', 'Es un robot' );
 }
}
add_filter('wp_authenticate_user', 'webheroe_verifica_recaptcha', 10, 2);

Añadimos la aceptación de la política de privacidad y el ReCAPTCHA en el formulario de registro

function recaptcha_privacidad_webheroe_reg() { ?>
    <p style="font-weight:300;font-size:14px;color:#fff;margin-bottom:10px;">
    <input type="checkbox" name="lp_privacy_policy" id="lp_privacy_policy" class="checkbox" required />
    Entiendo y estoy deacuerdo con la <a href="/enlace-a-politica-de-privacidad" target="_blank" style="color:inherit">política de privacidad</a>
    </p>
    <div style="margin-bottom:10px;" class="g-recaptcha" data-sitekey="CLAVE_PÚBLICA"></div>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
<?php
}
add_action( 'register_form', 'recaptcha_privacidad_webheroe_reg' );

Creamos nuevos errores en formulario de registro y realizamos la llamada a la API de Google

function webheroe_reg_errors( $errors, $sanitized_user_login, $user_email ) {
    if (!isset( $_POST['lp_privacy_policy'])){
        $errors->add( 'privacidad_error', "Politica de privacidad no aceptada" );
    }
    if(!isset($_POST["g-recaptcha-response"])){
        $errors->add( 'recaptcha_error', "Es un robot" );
    }else{
        
        //Verificamos Recaptcha
        $response = wp_remote_get('https://www.google.com/recaptcha/api/siteverify?secret=CLAVE_SECRETA&response=' . $_POST['g-recaptcha-response']);
        $response = json_decode($response['body'], true);
        if($response['success'] != true){
            $errors->add( 'recaptcha_mal', "Recaptcha no completado" );
        }
    }
    return $errors;
}
add_filter( 'registration_errors', 'webheroe_reg_errors', 10, 3 );

Insertamos los nuevos errores en la global $errors en caso de recibirlos al rellenar cualquiera de los formularios

function webheroe_errores_login() {
    global $errors;
    $err_codes = $errors->get_error_codes();
    $error = '';
    //Texto a mostrar si el usuario es incorrecto
    if ( in_array( 'invalid_username', $err_codes ) ) {
        $error .= 'Los datos son incorrectos<br>';
    }
    //Texto a mostrar si la contraseña es incorrecta
    if ( in_array( 'incorrect_password', $err_codes ) ) {
        $error .= 'Los datos son incorrectos<br>';
    }
    //Texto a mostrar si el recaptcha es incorrecto
    if ( in_array( 'recaptcha_mal', $err_codes ) ) {
        $error .= 'Por favor, rellene correctamente el Recaptcha<br>';
    }
    //Texto a mostrar si el recaptcha es incorrecto
    if ( in_array( 'privacidad_error', $err_codes ) ) {
        $error .= 'Por favor, acepte la política de privacidad<br>';
    }
    //Texto a mostrar si la respuesta de Google es incorrecta
    if ( in_array( 'recaptcha_error', $err_codes ) ) {
        $error .= 'Por favor, marchese si usted es un robot<br>';
    }
    return $error;
}
add_filter('login_errors','webheroe_errores_login');

Aquí os presento el código completo:

<?php
/***********************************************LOGIN****************************************************/
//Añadimos div donde se cargará el Recaptcha así como el script desde donde se carga la API de Google
function webheroe_login_recaptcha() {
 ?>
    <div style="margin-bottom:10px;" class="g-recaptcha" data-sitekey="CLAVE_PÚBLICA"></div>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    <?php
}
add_action( 'login_form', 'webheroe_login_recaptcha' );

//Verificación de usuario en el login
function webheroe_verifica_recaptcha($user, $password){
 if(isset($_POST['g-recaptcha-response'])){
    $response = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=CLAVE_SECRETA&response=' . $_POST['g-recaptcha-response'] );
    $response = json_decode($response['body'], true);
    if($response['success'] == true){
        return $user;
    }else{
        return new WP_Error( 'recaptcha_mal', 'Recaptcha no completado' );
    }
 }else{
    return new WP_Error( 'recaptcha_error', 'Es un robot' );
 }
}
add_filter('wp_authenticate_user', 'webheroe_verifica_recaptcha', 10, 2);

//Añadimos la aceptación de la política de privacidad y el recaptcha en la página de registro
function recaptcha_privacidad_webheroe_reg() { ?>
    <p style="font-weight:300;font-size:14px;color:#fff;margin-bottom:10px;">
    <input type="checkbox" name="lp_privacy_policy" id="lp_privacy_policy" class="checkbox" required />
    Entiendo y estoy deacuerdo con la <a href="/enlace-a-politica-de-privacidad" target="_blank" style="color:inherit">política de privacidad</a>
    </p>
    <div style="margin-bottom:10px;" class="g-recaptcha" data-sitekey="CLAVE_PÚBLICA"></div>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
<?php
}
add_action( 'register_form', 'recaptcha_privacidad_webheroe_reg' );

//Gestionamos los errores en formulario de registro
function webheroe_reg_errors( $errors, $sanitized_user_login, $user_email ) {
    if (!isset( $_POST['lp_privacy_policy'])){
        $errors->add( 'privacidad_error', "Politica de privacidad no aceptada" );
    }
    if(!isset($_POST["g-recaptcha-response"])){
        $errors->add( 'recaptcha_error', "Es un robot" );
    }else{
        
        //Verificamos Recaptcha
        $response = wp_remote_get('https://www.google.com/recaptcha/api/siteverify?secret=CLAVE_SECRETA&response=' . $_POST['g-recaptcha-response']);
        $response = json_decode($response['body'], true);
        if($response['success'] != true){
            $errors->add( 'recaptcha_mal', "Recaptcha no completado" );
        }
    }
    return $errors;
}
add_filter( 'registration_errors', 'webheroe_reg_errors', 10, 3 );

//Gestión de los errores obtenidos
function webheroe_errores_login() {
    global $errors;
    $err_codes = $errors->get_error_codes();
    $error = '';
    //Texto a mostrar si el usuario es incorrecto
    if ( in_array( 'invalid_username', $err_codes ) ) {
        $error .= 'Los datos son incorrectos<br>';
    }
    //Texto a mostrar si la contraseña es incorrecta
    if ( in_array( 'incorrect_password', $err_codes ) ) {
        $error .= 'Los datos son incorrectos<br>';
    }
    //Texto a mostrar si el recaptcha es incorrecto
    if ( in_array( 'recaptcha_mal', $err_codes ) ) {
        $error .= 'Por favor, rellene correctamente el Recaptcha<br>';
    }
    //Texto a mostrar si el recaptcha es incorrecto
    if ( in_array( 'privacidad_error', $err_codes ) ) {
        $error .= 'Por favor, acepte la política de privacidad<br>';
    }
    //Texto a mostrar si la respuesta de Google es incorrecta
    if ( in_array( 'recaptcha_error', $err_codes ) ) {
        $error .= 'Por favor, marchese si usted es un robot<br>';
    }
    return $error;
}
add_filter('login_errors','webheroe_errores_login');

Añadir ReCAPTCHA v3 en nuestra página de login

German Moyano, un colega de Linked In me ha preguntado sobre cómo implementar ReCAPTCHA v3 en nuestra página de login. Así que os explico un modo rápido y no muy complejo con el que podríamos hacerlo.

En este caso, las llamadas a la API se hacen de un modo ligeramente diferente. Y además he añadido un trocito de código jQuery para enviar con el formulario, vía POST, el token necesario para verificarse el ReCAPTCHA en el backend. También cargaremos jQuery mediante CDN antes de insertar el código de la API para asegurarnos que funciona perfectamente.

Cargamos el código en la página de login:

function webheroe_login_recaptchav3() {
	?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?render=CLAVE_PÚBLICA"></script>
	<script>
	jQuery(document).ready(function($){
		$('#loginform').submit(function(event) {
			event.preventDefault();
			grecaptcha.ready(function() {
				grecaptcha.execute('CLAVE_PÚBLICA', {action: 'webheroe_login'}).then(function(token) {
					$('#loginform').prepend('<input type="hidden" name="token" value="' + token + '">');
					$('#loginform').unbind('submit').submit();
				});
			});
	  });
	})
  </script>
	<?php
}
add_action( 'login_form', 'webheroe_login_recaptchav3');

Al tiempo que verificamos el usuario también lo hacemos con el ReCAPTCHA mediante el token obtenido anteriormente:

function webheroe_verifica_recaptchav3($user, $password){
	if(isset($_POST['token'])){
		$response = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=CLAVE_PRIVADA&response=' . $_POST['token'] );
		$response = json_decode($response['body'], true);
		
		if($response['success'] == true && $response['action'] == 'webheroe_login'){
			return $user;
		}else{
			return new WP_Error( 'recaptcha_error', 'Es un robot' );
		}
	}else{
		return new WP_Error( 'recaptcha_error', 'Es un robot' );
	}
}
add_filter('wp_authenticate_user', 'webheroe_verifica_recaptchav3', 10, 2);

Si tienes alguna pregunta, sugerencia o simplemente quieres dar tu opinión no lo dudes y deja tu comentario

Aviso Legal

Política de Privacidad

Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestra web. Si sigues utilizando este sitio asumiremos que estás de acuerdo