Widziałem kilka dyskusji na temat zmuszenia Wordpressa do zregenerowania unikalnego nonce'a dla kolejnych żądań Ajax, ale przez całe moje życie nie mogę zmusić Wordpressa do zrobienia tego - za każdym razem, gdy pytam, co moim zdaniem powinno być nowe nonce, dostaję ten sam nonce z Wordpress. Rozumiem koncepcję nonce_life WP, a nawet ustawienie jej na coś innego, ale to mi nie pomogło.
Nie generuję nonce w obiekcie JS w nagłówku poprzez lokalizację - robię to na mojej stronie wyświetlania. Mogę sprawić, że moja strona przetworzy żądanie Ajax, ale kiedy poproszę o nową wartość jednorazową z WP w wywołaniu zwrotnym, otrzymam tę samą wartość jednorazową i nie wiem, co robię źle ... Ostatecznie chcę rozszerz to, aby na stronie mogło znajdować się wiele elementów, każdy z możliwością dodawania / usuwania - więc potrzebuję rozwiązania, które pozwoli na wiele kolejnych żądań Ajax z jednej strony.
(I powinienem powiedzieć, że umieściłem całą tę funkcjonalność we wtyczce, więc „strona wyświetlająca” frontonu jest w rzeczywistości funkcją dołączoną do wtyczki ...)
functions.php: lokalizuj, ale nie tworzę tutaj nonce
wp_localize_script('myjs', 'ajaxVars', array('ajaxurl' => 'admin-ajax.php')));
Dzwonię do 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
}
}
});
});
Odbieranie 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();
}
Frontendowa funkcja wyświetlania PHP, między innymi:
$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>';
W tym momencie byłbym bardzo wdzięczny za wszelkie wskazówki lub wskazówki, które pozwolą WP zregenerować unikatowy nonce dla każdego nowego żądania Ajax ...
AKTUALIZACJA: Rozwiązałem mój problem. Powyższe fragmenty kodu są prawidłowe, jednak zmieniłem tworzenie $ newNonce w wywołaniu zwrotnym PHP, aby dodać ciąg mikrosekund, aby upewnić się, że jest unikalny dla kolejnych żądań Ajax.
Odpowiedzi:
Oto bardzo długa odpowiedź na moje własne pytanie, która wykracza poza samo pytanie o generowanie unikalnych wartości jednorazowych dla kolejnych żądań Ajax. Jest to funkcja „dodaj do ulubionych”, która została stworzona na potrzeby odpowiedzi (moja funkcja pozwala użytkownikom dodawać identyfikatory postów załączników do zdjęć do listy ulubionych, ale może to dotyczyć wielu innych funkcji, które polegają na Ajax). Zakodowałem to jako samodzielną wtyczkę, a brakuje kilku elementów - ale powinno to być wystarczająco szczegółowe, aby zapewnić sedno, jeśli chcesz powielić tę funkcję. Będzie działał na pojedynczym poście / stronie, ale będzie także działał na listach postów (np. Możesz dodawać / usuwać elementy do ulubionych w linii za pośrednictwem Ajax, a każdy post będzie miał swój unikalny kod dla każdego żądania Ajax). Pamiętaj, że tam ”
scripts.php
Favorites.js (wiele rzeczy do debugowania, które można usunąć)
Funkcje (wyświetlacz frontowy i działanie Ajax)
Aby wyświetlić link Dodaj / Usuń ulubione, po prostu zadzwoń na swoją stronę / post przez:
Funkcja wyświetlacza front-end:
Funkcja akcji Ajax:
źródło
Naprawdę muszę zakwestionować uzasadnienie otrzymania nowej wartości jednorazowej dla każdego żądania ajax. Oryginalna wartość jednorazowa wygaśnie, ale można z niej skorzystać więcej niż jeden raz, aż to nastąpi. Otrzymanie go przez javascript za pośrednictwem ajax pokonuje cel, zwłaszcza jeśli jest dostępny w przypadku błędu. (Celem jest, aby jednostki jednorazowe stanowiły niewielkie zabezpieczenie dla skojarzenia akcji z użytkownikiem w określonym czasie).
Nie powinienem wspominać o innych odpowiedziach, ale jestem nowy i nie mogę komentować powyżej, więc w odniesieniu do opublikowanego „rozwiązania” za każdym razem otrzymujesz nowy nonce, ale nie używasz go w żądaniu. Byłoby z pewnością trudne, aby mikrosekundy były takie same za każdym razem, aby dopasować każdą nową nonce utworzoną w ten sposób. Kod PHP weryfikuje oryginalną wartość jednorazową, a javascript dostarcza oryginalną wartość jednorazową ... więc działa (ponieważ jeszcze nie wygasła).
źródło
check_ajax_referer
zwraca -1, co nie jest tym, czego chcemy!