Ticker

6/recent/ticker-posts

Ad Code

Responsive Advertisement

Agregar recaptcha v3 en formulario de contacto

En un artículo anterior habíamos visto cómo tener un formulario de contacto en WordPress sin usar plugins, en este artículo vamos a agregar la funcionalidad de recaptcha a ese formulario.

 

Generalidades

El proceso para la validación de recaptcha consiste en usar un token, este token es generador por Google usando la clave pública, enviaremos ese token como parte del formulario.

Cuando el usuario haga uso del formulario entonces a nivel de servidor volvemos a validar ese token con la clave privada.

En la siguiente imagen se muestra un esquema general del funcionamiento de recaptcha.

Recaptcha proceso validación
Por simplicidad, este esquema considera que el token se genera cuando se devuelve la página con el formulario, otra opción es generar el token justo antes de enviar el formulario.

 

Creación de las claves recaptcha

Desde tu cuenta de recaptcha tienes la opción de generar nuevas claves para un sitio o sitios.

Creación de nuevo recaptcha

 

Luego tienes que seleccionar la versión de recaptcha que usarás, en nuestro caso usaremos la versión 3, además en la opción de dominios debes incluir el dominio o dominios que usarás, en nuestro caso el dominio de de prueba: wordpress6.local

Recaptcha versión selección

 
Finalmente se te proporcionarán las claves, tanto publica como privada que usaremos posteriormente en el código.

Clave pública y privada recaptcha

 

Código para usar recaptcha

Anteriormente ya habíamos implementado un formulario de contacto sin plugins, por lo que simplemente agregaremos la funcionalidad de recaptcha a ese formulario.

Para la implementación del código puedes revisar el artículo Formulario de contacto sin plugins en WordPress en donde se explica detalladamente la implementación del código base.

Archivo de plantilla de página

Modificaremos este archivo para adaptarlo a la funcionalidad de recaptcha, algunas de las modificaciones son:

  • Agregaremos la referencia al script externo: https://ift.tt/JmRBYZr, incluiremos la API pública a través de una constante, (agregaremos esa constante posteriormente en el archivo functions.php del tema hijo).
  • Hay una condicional para indicar un error de recaptcha cuando el valor devuelto es -1
  • En la parte inferior del archivo incluimos código javascript para recuperar el token de google cuando la página ya haya cargado.

<script src="https://www.google.com/recaptcha/api.js?render=<?= PUBLIC_KEY_RV3 ?>" ></script>

        <div id="primary" class="content-area">
                <main id="main" class="site-main" role="main">

                        <?php
            if ( isset($_GET['sent']) ){
                if ( $_GET['sent'] == '1'){
                    echo "<p class='msg'> ✔ Formulario enviado correctamente</p><br>";
                }
                elseif ($_GET['sent'] == '-1') {
                    echo "<p class='msg'> Error de recaptcha, puede ser que haya expirado, refresque el navegador e intente nuevamente </p><br>";
                } else {
                    echo "<p class='msg'> Hubo un error al enviar</p><br>";
                }
            }
            ?>
            <form id="frm-contact" method="post" action="<?php echo admin_url( 'admin-post.php' ) ?>" >
                <label for="name">Nombre:</label>
                <input type="text" name="name" id="name" required>
            
                <br>
                <label for="email">Correo:</label>
                <input type="email" name="email" id="email" required>
            
                <br>
                <label for="message">Mensaje:</label>
                <textarea name="message" id="message" cols="30" rows="10" required></textarea>
            
                <br>
                <p><input type="checkbox" id="terms" name="terms" required> Acepto los <a href="#">Términos y Condiciones</a></p>
            
                <br>
                <input type="hidden" name="action" value="process_form">

                <input type="submit" name="submit" value="Enviar" disabled>
            </form>

            <script>
                (function( $ ) {
                    $( document ).ready(function() {
                        grecaptcha.ready(function() {
                            grecaptcha.execute('<?= PUBLIC_KEY_RV3 ?>', {action: 'process_form'}).then(function(token) {
                                $('#frm-contact').prepend('<input type="hidden" name="token" value="' + token + '">');
                                $('#frm-contact input[type="submit"]').prop('disabled',false);
                            });
                        });                     
                    });
                    
                })( jQuery );
            </script>

                </main><!-- #main -->
        </div><!-- #primary -->
El código carga el token al inicio, en el evento “ready”, sin embargo el token tiene una expiración, por lo que si el usuario tarda más de 3 minutos es posible que el token expire. Si tienes este problema será mejor generar el token en el evento de envío del formulario.

 

Procesamiento del token recaptcha y envío de correo

Colocaremos el código necesario para procesar el formulario de contacto en un archivo separado en la siguiente ruta, dentro de tu tema hijo: includes/contacto.php

  • En este archivo hemos agregado la función validate_recaptcha()
  • En la función hacemos un llamado a la API de Google
  • Usamos la clave privada para hacer la petición y el token obtenido en el paso anterior
  • La API de Google devuelve un JSON que usaremos para comprobar si el formulario ha sido llenado por un humano

<?php

// Hooks admin-post
add_action( 'admin_post_nopriv_process_form', 'send_mail_data' );
add_action( 'admin_post_process_form', 'send_mail_data' );

// Funcion callback
function send_mail_data() {

        validate_recaptcha();

        $name = sanitize_text_field($_POST['name']);
        $email = sanitize_email($_POST['email']);
        $message = sanitize_textarea_field($_POST['message']);

        $adminmail = "destino@dominio.com"; //email destino
        $subject = 'Formulario de contacto'; //asunto
        $headers = "Reply-to: " . $name . " <" . $email . ">";

        //Cuerpo del mensaje
        $msg = "Nombre: " . $name . "\n";
        $msg .= "E-mail: " . $email . "\n\n";
        $msg .= "Mensaje: \n\n" . $message . "\n";

        $sendmail = wp_mail( $adminmail, $subject, $msg, $headers);

        wp_redirect( home_url("/contacto/")."?sent=".$sendmail ); //asumiendo que existe esta url
        exit;
}


function validate_recaptcha(){
    $token = $_POST['token'];
    $action = $_POST['action'];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('secret' => PRIVATE_KEY_RV3, 'response' => $token)));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    $arrResponse = json_decode($response, true);

    // verify the response
    if($arrResponse["success"] != '1' || $arrResponse["action"] != $action || $arrResponse["score"] < 0.5) {
                wp_redirect( home_url("/contacto/")."?sent=-1" );
                exit;
    }
}

 

Código en el archivo functions.php

Finalmente para hace referencia al archivo includes/contacto.php, necesitaremos incluirlo desde el archivo functions.php de tu tema hijo, además definiremos también las constantes de las claves publicas y privadas en este archivo.


define('PUBLIC_KEY_RV3', 'xxxxxxxx');
define('PRIVATE_KEY_RV3', 'xxxxxxxx');
include_once('includes/contacto.php');

 

Conclusión

Como has podido comprobar, podemos agregar funcionalidad al formulario de contacto que habíamos realizado en un artículo anterior, en este caso hemos agregado la comprobación de recaptcha para evitar el spam.

 
¿Aún con dudas?, en el siguiente video se detallan los puntos anteriores.

Suscríbete a DecodeCMS:  

 

La entrada Agregar recaptcha v3 en formulario de contacto es un artículo reciente del sitio DecodeCMS.

Enregistrer un commentaire

0 Commentaires