Cum să configurezi corect un nonce AJAX pentru API REST în WordPress
Urmând un comentariu cu link aici care m-a condus la aceste documente, am încercat să configurez un nonce pentru autentificarea utilizatorilor.
Am adăugat:
wp_localize_script( 'wp-api', 'wpApiSettings', array(
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' )
) );
la instrucțiunea if care verifică dacă utilizatorul este autentificat și poate face operațiunile cerute în apelul REST.
De asemenea, am adăugat:
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
},
la clasa jQuery a apelului meu API.
Am primit o eroare care îmi spune că wpApiSettings nu există. Ce am greșit?

Pentru început...
(Această informație este pentru alți cititori care nu știu încă despre asta.) Există două modalități prin care vă puteți autentifica cererea REST API:
Folosind autentificarea standard prin cookie
Folosind un plugin precum Application Passwords
Puteți citi mai multe în manualul oficial REST API aici, iar acest răspuns este pentru autentificarea standard prin cookie, unde nonce-ul trebuie să fie trimis fie prin parametrul de interogare GET/POST
numit _wpnonce
, fie prin antetul (HTTP personalizat) numit X-WP-Nonce
.
Opțiuni pentru trimiterea nonce-ului prin cookie
Opțiunea simplă: Adăugați
_wpnonce
la URL-ul endpoint-ului REST API. Aceasta funcționează cu cereriGET
,POST
, etc., inclusiv cu payload-uri JSON.jQuery.ajax({ method: 'POST', // _wpnonce ca parametru de interogare GET/$_GET url: '/path/to/endpoint?_wpnonce=<nonce>', data: { foo: 'bar', baz: 1 }, dataType: 'json', success: function ( data ) { console.log( data ); }, });
Sau adăugați
_wpnonce
în corpul cererii.jQuery.ajax({ method: 'POST', url: '/path/to/endpoint', // _wpnonce ca parametru de interogare POST/$_POST // dar poate fi GET; vedeți `method` de mai sus care implicit este GET când nu este specificat data: { foo: 'bar', baz: 1, _wpnonce: '<nonce>' }, dataType: 'json', success: function ( data ) { console.log( data ); }, });
Sau în special când trimiteți un payload JSON (exact ca în exemplul din această întrebare): Adăugați
X-WP-Nonce
în anteturile cererii. Această opțiune funcționează și cu cereriGET
,POST
, etc.jQuery.ajax({ method: 'POST', url: '/path/to/endpoint', data: JSON.stringify( { foo: 'bar', baz: 1 } ), // trimiterea unui șir codificat JSON contentType: 'application/json; charset=utf-8', // și un antet Content-Type JSON // Trimiteți nonce-ul ca parte a antetelor. beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', '<nonce>' ); }, dataType: 'json', success: function ( data ) { console.log( data ); }, });
Acum un exemplu:
Partea PHP: (în fișierul de funcții al temei sau al plugin-ului)
// Înregistrați un endpoint dummy REST API..
add_action( 'rest_api_init', 'my_register_rest_routes' );
function my_register_rest_routes() {
register_rest_route( 'my-plugin/v1', '/foo', [
'methods' => 'POST',
'callback' => function ( $request ) {
return [
$request->get_params(),
'Utilizator autentificat: ' . ( is_user_logged_in() ? 'Da' : 'NU' ),
'Utilizatorul poate publica postări: ' . ( current_user_can( 'publish_posts' ) ? 'Da' : 'NU' )
];
},
] );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );
function my_enqueue_scripts() {
// Încărcați scriptul care face apelul AJAX către /wp-json/my-plugin/v1/foo.
wp_enqueue_script( 'my-script', '/path/to/my-script.js', [ 'jquery' ] );
// Înregistrați variabile personalizate pentru scriptul AJAX.
wp_localize_script( 'my-script', 'myScriptVars', [
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' ),
] );
}
Note:
Amintiți-vă că primul parametru pentru
wp_enqueue_script()
—my-script
în exemplul de mai sus — este exact același cu primul parametru pentruwp_localize_script()
. Și acel parametru este handle-ul scriptului, care este un slug unic ca identificator pentru scriptul pe care îl încărcați sau localizați.Dacă acei parametri nu se potrivesc, atunci scriptul nu va fi localizat, iar obiectul JS —
myScriptVars
în exemplul de mai sus — va fiundefined
, ceea ce ar putea duce la eroarea menționată în întrebare ("wpApiSettings nu există"). :)
Partea JS: (în my-script.js
sau oricare este numele fișierului...)
Aici, adăugăm _wpnonce
în corpul cererii.
jQuery.ajax({
method: 'POST',
url: myScriptVars.root + 'my-plugin/v1/foo',
data: { foo: 'bar', baz: 1, _wpnonce: myScriptVars.nonce },
dataType: 'json',
success: function ( data ) {
console.log( data );
},
});
Note:
Codul JS de mai sus și celelalte din acest răspuns folosesc ajax()
din jQuery.

Ah, desigur! Mă simt atât de prost, evident că localizarea trebuie făcută înaintea headerelor. Doh. Răspuns excelent.

Notă pentru cei mai lenți dintre noi (ca mine) - primul parametru al funcției wp_localize_script
este handle-ul cu care ai înregistrat scriptul tău când l-ai adăugat în coadă.
