¿Qué es nonce y cómo usarlo con Ajax en WordPress?
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?

¡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?
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.
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.
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... } }, } );
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á.
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')
dewpdocs_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.

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.

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.

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

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

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