Funcția wp_get_current_user() nu funcționează în callback-ul API-ului REST
Luați în considerare următoarea clasă.
<?php
class MCQAcademy_Endpoint extends WP_REST_Controller {
/**
* Înregistrează rutele pentru obiectele controlerului.
*/
public function register_routes() {
$version = '1';
$namespace = 'custompath/v' . $version;
$base = 'endpointbase';
register_rest_route(
$namespace,
'/' . $base,
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(),
)
)
);
}
/**
* Obține articolele
*/
public function get_items( $request ) {
$rs = array(
'data' => array(),
'request' => array(
'lang' => 'en',
),
);
$args = array();
$items = get_posts( $args );
foreach( $items as $item ) {
$itemdata = $this->prepare_item_for_response( $item, $request );
$rs['data'][] = $this->prepare_response_for_collection( $itemdata );
}
$rs['wp_get_current_user'] = wp_get_current_user(); // Nu afișează cum te-ai aștepta
return new WP_REST_Response( $rs, 200 );
}
/**
* Verifică dacă o cerere dată are acces pentru a obține articole
*/
public function get_items_permissions_check( $request ) {
return true; // pentru a face accesibil tuturor
}
/**
* Pregătește elementul pentru operația de creare sau actualizare
*/
protected function prepare_item_for_database( $request ) {
return $request;
}
/**
* Pregătește elementul pentru răspunsul REST
*/
public function prepare_item_for_response( $item, $request ) {
$data = array(
'ID' => $item->ID,
'post_content' => wpautop($item->post_content),
'post_title' => $item->post_title,
);
return $data;
}
/**
* Obține parametrii de interogare pentru colecții
*/
public function get_collection_params() {
return array(
'page' => array(
'description' => 'Pagina curentă a colecției.',
'type' => 'integer',
'default' => 1,
'sanitize_callback' => 'absint',
),
'per_page' => array(
'description' => 'Numărul maxim de articole de returnat în setul de rezultate.',
'type' => 'integer',
'default' => 10,
'sanitize_callback' => 'absint',
),
'search' => array(
'description' => 'Limitează rezultatele la cele care se potrivesc cu un șir.',
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
);
}
// Înregistrează serverul nostru REST
public function hook_rest_server(){
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
}
$myEndpoint = new MCQAcademy_Endpoint();
$myEndpoint->hook_rest_server();
Totul funcționează bine, cu excepția apelului funcției wp_get_current_user()
în funcția get_items()
care returnează un utilizator gol, chiar dacă utilizatorul este autentificat
pe site.

Faptul că un utilizator este autentificat pe site-ul tău nu înseamnă că este autentificat și în cererile către REST API, de aceea nu obții utilizatorul corect sau un Id = 0
.
Te rugăm să consulți metodele de autentificare pentru REST API din documentație:
https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/
Pentru dezvoltatorii care fac cereri Ajax manuale, nonce-ul va trebui să fie transmis cu fiecare cerere. API-ul folosește nonce-uri cu acțiunea setată la wp_rest. Acestea pot fi transmise către API prin parametrul de date _wpnonce (fie în datele POST, fie în interogare pentru cererile GET), sau prin antetul X-WP-Nonce. Dacă nu este furnizat niciun nonce, API-ul va seta utilizatorul curent la 0, transformând cererea într-una neautentificată, chiar dacă ești autentificat în WordPress.
Pentru autentificare la distanță, aș recomanda plugin-ul JWT pentru un început rapid:
Sau poți folosi cele sugerate în documentație:

Am nevoie de ID-ul utilizatorului dacă acesta este autentificat pe site. Deoarece endpoint-ul este deschis, nu este nevoie să verific permisiunile.

Această linie întoarce întotdeauna false, chiar dacă utilizatorul este autentificat pe site.
$rs['wp_get_current_user'] = is_user_logged_in() ? get_current_user_id() : false;

Salut @ShahAlom, așa cum am menționat în răspunsul meu, autentificarea pe site nu este aceeași cu autentificarea în REST API, te rog să consulți documentația privind metodele de autentificare în REST API: https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/

Pentru autentificarea prin cookie: Pentru dezvoltatorii care fac cereri Ajax manuale, nonce-ul va trebui să fie transmis cu fiecare cerere. API-ul folosește nonce-uri cu acțiunea setată la wp_rest. Acestea pot fi apoi transmise către API prin parametrul de date _wpnonce (fie prin date POST, fie în interogare pentru cererile GET), sau prin antetul X-WP-Nonce. Dacă nu este furnizat niciun nonce, API-ul va seta utilizatorul curent la 0, transformând cererea într-una neautentificată, chiar dacă sunteți conectat la WordPress.

Te rog actualizează răspunsul tău cu acest ultim comentariu, astfel încât să îl pot accepta ca soluție.

Chiar și cu autentificarea JWT, tot trebuie să transmiți antetul X-WP-Nonce pentru a obține utilizatorul curent, de exemplu dacă ai nevoie să accesezi users/me tot returnează 401, la fel și pentru interogarea utilizatorilor după rol și așa mai departe. Cererile AJAX "ne-manuale" sunt "speciale" doar pentru că clientul oficial de API include acel antet, dar nimic altceva.

@JesúsFranco din experiența mea de utilizare a plugin-ului JWT, nu este nevoie să trimiți niciun header suplimentar, doar header-ul Authorization cu token-ul generat anterior pentru autentificare, /wp-v2/users/me
funcționează pentru mine

Hmmm, asta mă face să mă gândesc ce ar putea fi diferit de la o configurare la alta, versiunea plugin-ului? A nucleului?

Gândindu-mă la care ar putea fi diferențele, am observat două tipuri de cereri care sunt interzise fără utilizarea nonce-ului și permise fără el, de asemenea. Diferența pe care am observat-o este mediul din care se face cererea. Cererile prin intermediul unui script PHP sunt permise doar cu Token-ul fiind suficient, cererile prin browser nu sunt permise fără nonce.

@JesúsFranco ai dreptate, pentru cererile pe partea de server (cazul meu), token-ul va fi suficient, pentru apelurile client side/manuale ajax, trebuie să incluzi nonce pentru a evita CSRF, nu este nevoie să incluzi token-ul deoarece deja ai un utilizator autentificat și partea de client se bazează pe cookie-uri

Dacă un apel API sosește fără un nonce setat, WordPress va dezautentifica cererea, întrerupând utilizatorul curent și făcând cererea neautentificată. Această protecție CSFR este automată și nu trebuie să faci nimic pentru ca aceasta să funcționeze, în afară de includerea nonce-ului.
Soluția este să incluzi un nonce. Ceva de genul:
$_wpnonce = wp_create_nonce( 'wp_rest' );
echo "<input type = 'hidden' name = '_wpnonce' value = '$_wpnonce' />";
Și să-l incluzi în cererea ta API. Nonce-ul trebuie să se numească "_wpnonce", iar acțiunea trebuie să fie "wp_rest" pentru ca API-ul să funcționeze. Acesta poate fi inclus în URL sau în corpul postării.

Pentru a avea un exemplu complet de cod funcțional, iată un exemplu de modul în care poți obține ID-ul utilizatorului curent prin intermediul REST.
my-plugin.php
class MyPlugin {
public function __construct() {
add_action('wp_enqueue_scripts', [$this, 'scripts']);
add_action('rest_api_init', [$this, 'rest']);
}
function scripts() {
// Adaugă JS.
wp_enqueue_script('my-plugin', plugin_dir_url(__FILE__) . 'js/scripts.js', ['jquery'], NULL, TRUE);
// Transmite nonce către JS.
wp_localize_script('my-plugin', 'MyPluginSettings', [
'nonce' => wp_create_nonce('wp_rest'),
]);
}
function rest() {
// Înregistrează ruta.
register_rest_route('my-plugin/v1', '/uid', [
'methods' => WP_REST_Server::READABLE,
'callback' => [$this, 'rest_callback'],
]);
}
function rest_callback($data) {
// Obține ID-ul utilizatorului curent.
$data = [
'uid' => get_current_user_id(),
];
$response = new WP_REST_Response($data, 200);
// Setează headerele.
$response->set_headers(['Cache-Control' => 'must-revalidate, no-cache, no-store, private']);
return $response;
}
}
new MyPlugin();
js/scripts.js
(function($) {
$(document).ready(function() {
var settings = MyPluginSettings;
$.ajax({
url: '/wp-json/my-plugin/v1/uid',
method: 'GET',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-WP-Nonce', settings.nonce);
}
}).done(function(response) {
// Va returna UID-ul tău.
console.log(response);
});
});
})(jQuery);
Resursă: https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/

Nu înțeleg cum este transmis 'MyPluginSettings' către script. Lucruri posibile de luat în considerare: în prezent nu folosesc JQuery, ci JavaScript "vanilla"... Am introdus scriptul meu în tag-uri HTML <script> atunci când era nevoie, dar am încercat să le includ cu wp_enqueue_script și am avut aceeași problemă.

Am reușit să rezolv, am scris greșit calea când am adaptat pentru wp_enqueue_script(). De asemenea, aveam mai multe scripturi și abia acum am înțeles că primul parametru al wp_enqueue_script() nu este specific plugin-ului, ci este specific scriptului (poate ar trebui să schimbați 'my-plugin' în răspunsul dumneavoastră pentru că este confuz.

wp_get_current_user()
nu funcționează deoarece utilizatorul tău nu este setat corect. Vezi codul de mai jos din /wp-includes/user.php
pentru referință.
if ( ! empty( $current_user ) ) {
if ( $current_user instanceof WP_User ) {
return $current_user;
}
// Upgrade stdClass la WP_User
if ( is_object( $current_user ) && isset( $current_user->ID ) ) {
$cur_id = $current_user->ID;
$current_user = null;
wp_set_current_user( $cur_id );
return $current_user;
}
// $current_user are o valoare invalidă. Forțează WP_User cu ID 0.
$current_user = null;
wp_set_current_user( 0 );
return $current_user;
}
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
wp_set_current_user( 0 );
return $current_user;
}
Tot ce trebuie să faci este să apelezi wp_set_current_user( {user_id} ) la începutul API-ului tău.
