Eu já vi algumas discussões sobre como fazer com que o Wordpress regenere um nonce exclusivo para solicitações subsequentes do Ajax, mas, para a minha vida, não consigo fazer com que o Wordpress faça isso - toda vez que solicito o que acho que deveria ser um novo nonce, recebo o mesmo nonce de volta do Wordpress. Entendo o conceito de nonce_life do WP e até defini-lo para outra coisa, mas isso não me ajudou.
Eu não giro o nonce no objeto JS no cabeçalho via localização - faço na minha página de exibição. Posso fazer com que minha página processe a solicitação do Ajax, mas quando solicito um novo nonce do WP no retorno de chamada, recebo o mesmo nonce de volta e não sei o que estou fazendo de errado ... Finalmente, quero estenda isso para que possa haver vários itens na página, cada um com a capacidade de adicionar / remover - por isso, preciso de uma solução que permita várias solicitações subsequentes do Ajax em uma página.
(E devo dizer que coloquei toda essa funcionalidade em um plug-in, portanto, a "página de exibição" do front-end é na verdade uma função incluída no plug-in ...)
functions.php: localize, mas não crio um nonce aqui
wp_localize_script('myjs', 'ajaxVars', array('ajaxurl' => 'admin-ajax.php')));
Chamando 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
}
}
});
});
Recebendo 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();
}
Função de exibição PHP front-end, entre as quais:
$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>';
Nesse momento, ficaria muito grato por qualquer pista ou indicação de fazer o WP regenerar um noncece único para cada nova solicitação do Ajax ...
ATUALIZAÇÃO: Eu resolvi meu problema. Os trechos de código acima são válidos, no entanto, alterei a criação de $ newNonce no retorno de chamada PHP para anexar uma sequência de microssegundos para garantir que ela seja exclusiva nas solicitações subsequentes do Ajax.
Respostas:
Aqui está uma resposta muito longa da minha própria pergunta que vai além de apenas abordar a questão de gerar nonces únicos para solicitações subsequentes do Ajax. Esse é um recurso "adicionar aos favoritos", que foi tornado genérico para os fins da resposta (meu recurso permite que os usuários adicionem os IDs de postagem de anexos de fotos a uma lista de favoritos, mas isso pode se aplicar a vários outros recursos que dependem de Ajax). Eu codifiquei isso como um plug-in independente e faltam alguns itens - mas isso deve ser suficiente para fornecer a essência, se você quiser replicar o recurso. Ele funcionará em uma postagem / página individual, mas também funcionará em listas de postagens (por exemplo, você pode adicionar / remover itens dos favoritos em linha via Ajax e cada postagem terá seu próprio nonce exclusivo para cada solicitação do Ajax). Lembre-se de que existe
scripts.php
favorites.js (Muitas coisas de depuração que podem ser removidas)
Funções (exibição front-end e ação do Ajax)
Para gerar o link Adicionar / Remover Favoritos, basta chamá-lo em sua página / postagem via:
Função de exibição frontal:
Função de ação Ajax:
fonte
Eu realmente tenho que questionar o raciocínio por trás de obter um novo nonce para cada solicitação de ajax. O nonce original expirará, mas poderá ser usado mais de uma vez até que exista. O recebimento do javascript através do ajax anula o objetivo, especialmente fornecendo-o em um caso de erro. (O objetivo de nonces ser um pouco de segurança para associar uma ação a um usuário dentro de um período de tempo.)
Não devo mencionar outras respostas, mas sou novo e não posso comentar acima. Portanto, no que diz respeito à "solução" postada, você recebe um novo aviso sempre que não o está usando na solicitação. Certamente seria difícil obter os microssegundos sempre o mesmo para corresponder a cada novo nonce criado dessa maneira. O código PHP está sendo verificado com relação ao nonce original e o javascript está fornecendo o nonce original ... portanto, ele funciona (porque ainda não expirou).
fonte
check_ajax_referer
retorna -1, o que não é o que queremos!