¿Qué es nonce y cómo usarlo con Ajax en WordPress?

8 jul 2016, 18:42:19
Vistas: 46.2K
Votos: 9

Estoy tratando de aprender cómo usar Ajax en WordPress de la manera correcta. Esto es lo que he aprendido:

Paso 1: Crear el archivo Ajax y registrarlo usando wp_enqueue_script.

function wpdocs_theme_name_scripts() {
    wp_enqueue_script( 'script-name', get_stylesheet_directory_uri() . '/js/ajxfile.js', array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'wpdocs_theme_name_scripts' );

Paso 2: Usar ajax de esta manera en ajxfile.js:

$( document ).ready(function() {

$('#id').on('click',function (e){       
    alert("Está funcionando");
    var up = 1;
    var id = $( "#id" ).data( "user_id" );
    $.ajax({
            type: "POST",
                url: "runcode.php",
                data: {up:up, id:id},
                success:
                    function(result){
                alert("resultado");
                        }
        });
});

});

PASO 3: agregando HTML en la página:

<a href="#" id="id" data-user_id="<?php echo $user_id = get_current_user_id(); ?>" 
data-post_id="<?php echo $post_id = get_the_ID(); ?>">
         <i class="fa fa-thumbs-up" aria-hidden="true"></i>
</a>

Cada vez que alguien hace clic en el enlace, muestra correctamente la alerta "Está funcionando". Ahora quiero recuperar esos datos y agregarlos en el meta de usuario. Pero me está confundiendo. ¿Y qué es esa cosa llamada nonce? ¿Alguien puede guiarme en la dirección correcta?

5
Comentarios

nonce es un identificador único que luego puedes validar con php para asegurarte de que es una solicitud válida y limpia, se genera mediante la función wp_create_nonce() y se verifica con wp_verify_nonce() o con el parámetro $_GET, o la forma preferida filter_input(INPUT_GET, '$nonce');

knif3r knif3r
8 jul 2016 18:47:33

¿Pero por qué WordPress lo recomienda? ¿y cómo debería usarlo con ajax?

Ramesh Pardhi Ramesh Pardhi
8 jul 2016 18:49:48

WordPress lo recomienda porque es bueno, no, la mejor manera de verificar si tu solicitud proviene de donde quieres y como quieres. Usándolo con ajax: creas el nonce en un campo de entrada oculto, por ejemplo, y lo obtienes con js para que puedas pasarlo con los otros datos de la solicitud, luego usas el parámetro GET en php para validarlo

knif3r knif3r
8 jul 2016 18:52:25

https://codex.wordpress.org/Function_Reference/check_ajax_referer Aquí puedes encontrar algunos buenos ejemplos de cómo y por qué usarlo. :)

knif3r knif3r
8 jul 2016 18:55:00

Se espera que investigues, al menos en nuestro sitio, antes de hacer una pregunta. Hemos cubierto esto muchas veces.

fuxia fuxia
8 jul 2016 20:47:49
Todas las respuestas a la pregunta 1
7
42

¡Ahora lo entiendo! WordPress es simplemente increíble. También gracias knif3r, tus sugerencias me ayudaron mucho. Estoy tratando de explicarlo con mis palabras. Por favor corrígeme si estoy equivocado.

¿Qué es un nonce?

Un nonce es algo así como un hash de seguridad para prevenir ataques y errores. Crea identificadores únicos para verificar si la solicitud ajax proviene del sitio web o no. En palabras de WordPress:

Un nonce es un "número usado una vez" para ayudar a proteger URLs y formularios de ciertos tipos de uso indebido, malicioso o no. Los nonces de WordPress no son números, sino un hash compuesto por números y letras. Tampoco se usan solo una vez, sino que tienen un "tiempo de vida" limitado después del cual expiran.

¿Cómo usarlo?

  1. Primero necesitamos agregar nuestro archivo JS correctamente usando wp_enqueue_script(). Algo así:

     function wpdocs_theme_name_scripts() {
         wp_enqueue_script( 'script-name', get_stylesheet_directory_uri().
             '/js/ajxfile.js', array(), '1.0.0', true );
     }
     add_action( 'wp_enqueue_scripts', 'wpdocs_theme_name_scripts' );
    

Registramos nuestro archivo ajxfile.js con el nombre script-name. Ahora se carga en todas las páginas de nuestro WordPress.

  1. Ahora necesitamos usar wp_localize_script() para declarar nuestras variables y aquí agregamos nuestro nonce para usarlo en las funciones.

     function wpdocs_theme_name_scripts() {
         wp_enqueue_script( 'script-name', get_stylesheet_directory_uri() . 
             '/js/ajxfile.js', array(), '1.0.0', true );
         wp_localize_script('script-name', 'ajax_var', array(
             'url' => admin_url('admin-ajax.php'),
             'nonce' => wp_create_nonce('ajax-nonce')
         ));
     }
    

Hemos registrado y localizado nuestro script exitosamente.

  1. Asegúrate de pasar los datos del nonce en tu llamada ajax en ajxfile.js:

     /* global ajax_var */
     $.ajax( {
         url: ajax_var.url,
         type: 'post',
         data: {
             action: 'custom_script_name',
             nonce: ajax_var.nonce,   // pasa el nonce aquí
             moredata: 'whatever',
         },
         success( data ) {
             if ( data ) {
                 // etc...
             }
         },
     } );
    
  1. Ahora queremos vincular nuestra función con nuestro script. Así que usé esto:

     add_action('wp_ajax_nopriv_custom_script_name', 'custom_php_ajax_function');    
     add_action('wp_ajax_custom_script_name', 'custom_php_ajax_function');
    

Estamos usando wp_ajax_nopriv_ y wp_ajax_ para vincular nuestras funciones con los hooks de WordPress. El segundo hook se activa cuando un usuario está logueado y el primero cuando no lo está.

  1. Nuestra función será así:

     function custom_php_ajax_function() {
         // Verifica la seguridad del nonce      
         if ( ! wp_verify_nonce( $_POST['nonce'], 'ajax-nonce' ) ) {
             die ( '¡Atrapado!');
         }
     }
    

Nuestra función verificará si los datos ajax están enviando el dato oculto nonce con otros parámetros. Si no lo hace, disparará un error. Esto realmente puede ayudar a prevenir ataques ajax. El dato nonce es un valor oculto y debe enviarse con los otros parámetros.

¿Cómo verificar si está funcionando o no?

  • Elimina 'nonce' => wp_create_nonce('ajax-nonce') de wpdocs_theme_name_scripts() y haz clic en el enlace. Mostrará un error.
  • Ahora elimina la verificación de seguridad de nuestra función y haz clic en el enlace. Funcionará.

Esto muestra que nuestra función con la verificación de seguridad del nonce nunca funcionará si no hay datos de nonce. Está oculto, así que nadie más puede usarlo. Y si nadie lo conoce, no importa cuántas veces ejecuten ese ajax, nuestra función no les responderá.

Disculpen mi pobre inglés y mala explicación. Solo trato de ayudar. Por favor avísame si me falta algo o hice algo mal.

8 jul 2016 20:06:50
Comentarios

Un pequeño detalle: wp_ajax_nopriv_ es para usuarios que NO han iniciado sesión (no tienen "privilegios"), y wp_ajax_ es para usuarios que han iniciado sesión. Lo mencionaste al revés.

scott scott
8 jul 2016 21:02:02

Parece que lo entendiste bien :) Solo recuerda usar opciones de filtrado cuando utilices solicitudes POST/GET/REQUEST como filter_input(INPUT_POST 'datasource'); u otras funciones de php como htmlspecialchars() y esc_attr() o esc_html cuando uses campos ocultos para pasar datos a js y estarás listo.

knif3r knif3r
8 jul 2016 21:29:01

Gracias Scott, actualicé la respuesta. Sí knif3r, gracias por la sugerencia. Lo tendré en cuenta.

Ramesh Pardhi Ramesh Pardhi
9 jul 2016 10:36:15

buena respuesta. Acabo de agregar el paso donde los datos del nonce deben pasarse en la llamada $.ajax

squarecandy squarecandy
28 ene 2021 01:48:45

Muy bien explicado - gracias

Clinton Clinton
15 mar 2021 17:06:12

Esto ayuda mucho pero no entiendo por qué siempre obtengo 0 en el cuerpo de la respuesta.

noob noob
1 nov 2022 12:55:43

Bien explicado @RameshPardhi

Krupal Panchal Krupal Panchal
1 dic 2022 11:37:50
Mostrar los 2 comentarios restantes