He visto un par de discusiones sobre cómo hacer que Wordpress regenere un nonce único para solicitudes posteriores de Ajax, pero por mi vida no puedo hacer que Wordpress lo haga, cada vez que solicito lo que creo que debería ser un nuevo nonce, recibo el mismo nonce de Wordpress. Entiendo el concepto de nonce_life de WP e incluso establecerlo en otra cosa, pero eso no me ha ayudado.
No genero el nonce en el objeto JS en el encabezado a través de la localización, lo hago en mi página de visualización. Puedo hacer que mi página procese la solicitud de Ajax, pero cuando solicito un nuevo nonce de WP en la devolución de llamada, recibo el mismo nonce y no sé qué estoy haciendo mal ... Finalmente quiero extienda esto para que pueda haber múltiples elementos en la página, cada uno con la capacidad de agregar / eliminar, por lo que necesito una solución que permita múltiples solicitudes posteriores de Ajax desde una página.
(Y debo decir que he puesto toda esta funcionalidad en un complemento, por lo que la "página de visualización" frontal es en realidad una función incluida con el complemento ...)
functions.php: localize, pero no creo un nonce aquí
wp_localize_script('myjs', 'ajaxVars', array('ajaxurl' => 'admin-ajax.php')));
Llamando a JS:
$("#myelement").click(function(e) {
e.preventDefault();
post_id = $(this).data("data-post-id");
user_id = $(this).data("data-user-id");
nonce = $(this).data("data-nonce");
$.ajax({
type: "POST",
dataType: "json",
url: ajaxVars.ajaxurl,
data: {
action: "myfaves",
post_id: post_id,
user_id: user_id,
nonce: nonce
},
success: function(response) {
if(response.type == "success") {
nonce = response.newNonce;
... other stuff
}
}
});
});
Recibiendo PHP:
function myFaves() {
$ajaxNonce = 'myplugin_myaction_nonce_' . $postID;
if (!wp_verify_nonce($_POST['nonce'], $ajaxNonce))
exit('Sorry!');
// Get various POST vars and do some other stuff...
// Prep JSON response & generate new, unique nonce
$newNonce = wp_create_nonce('myplugin_myaction_nonce_' . $postID . '_'
. str_replace('.', '', gettimeofday(true)));
$response['newNonce'] = $newNonce;
// Also let the page process itself if there is no JS/Ajax capability
} else {
header("Location: " . $_SERVER["HTTP_REFERER"];
}
die();
}
Función de visualización PHP frontend, entre las cuales se encuentra:
$nonce = wp_create_nonce('myplugin_myaction_nonce_' . $post->ID);
$link = admin_url('admin-ajax.php?action=myfaves&post_id=' . $post->ID
. '&user_id=' . $user_ID
. '&nonce=' . $nonce);
echo '<a id="myelement" data-post-id="' . $post->ID
. '" data-user-id="' . $user_ID
. '" data-nonce="' . $nonce
. '" href="' . $link . '">My Link</a>';
En este punto, estaría realmente agradecido por cualquier pista o indicador para que WP regenere un nonce único para cada nueva solicitud de Ajax ...
ACTUALIZACIÓN: he resuelto mi problema. Los fragmentos de código anteriores son válidos, sin embargo, cambié la creación de $ newNonce en la devolución de llamada de PHP para agregar una cadena de microsegundos para garantizar que sea única en las solicitudes posteriores de Ajax.
Respuestas:
Aquí hay una respuesta muy larga de mi propia pregunta que va más allá de solo abordar la cuestión de generar nonces únicos para solicitudes posteriores de Ajax. Esta es una función de "agregar a favoritos" que se hizo genérica a los efectos de la respuesta (mi función permite a los usuarios agregar las ID de publicación de archivos adjuntos de fotos a una lista de favoritos, pero esto podría aplicarse a una variedad de otras funciones que dependen de Ajax). Codifiqué esto como un complemento independiente, y faltan algunos elementos, pero esto debería ser suficiente detalle para proporcionar la esencia si desea replicar la función. Funcionará en una publicación / página individual, pero también funcionará en listas de publicaciones (por ejemplo, puede agregar / eliminar elementos a favoritos en línea a través de Ajax y cada publicación tendrá su propio nonce único para cada solicitud de Ajax). Tenga en cuenta que hay '
scripts.php
favorites.js (Muchas cosas de depuración que se pueden eliminar)
Funciones (pantalla frontal y acción Ajax)
Para generar el enlace Agregar o quitar favoritos, simplemente instálelo en su página / publicación a través de:
Función de visualización frontal:
Función de acción Ajax:
fuente
Realmente tengo que cuestionar el razonamiento detrás de obtener un nuevo nonce para cada solicitud de ajax. El nonce original caducará, pero puede usarse más de una vez hasta que lo haga. Hacer que JavaScript lo reciba a través de ajax anula el propósito, especialmente al proporcionarlo en un caso de error. (El propósito de nonces ser un poco de seguridad para asociar una acción con un usuario dentro de un marco de tiempo).
Se supone que no debo mencionar otras respuestas, pero soy nuevo y no puedo comentar más arriba, por lo que en lo que respecta a la "solución" publicada, está recibiendo un nuevo nonce cada vez pero no lo está utilizando en la solicitud. Ciertamente sería complicado obtener los microsegundos iguales cada vez para que coincidan con cada nuevo nonce creado de esa manera. El código PHP está verificando contra el nonce original, y el javascript está suministrando el nonce original ... por lo que funciona (porque aún no ha expirado).
fuente
check_ajax_referer
devuelve -1, ¡lo cual no es lo que queremos!