Richiesta Nonces e Ajax all'API REST e verifica

Nov 03 2020

Ho costruito il mio primo WordPress in oltre un decennio ... utilizzando Timber per MVC. Vue sul frontend e assi per i post ajax. Tutti ospitati sullo stesso dominio, quindi posso utilizzare i cookie per l'autenticazione.

Sto accodando axios e impostando un nonce come variabile locale che prendo nel mio Vue e utilizzo per impostare l'intestazione durante la pubblicazione tramite axios.

Ho un numero di percorsi API personalizzati registrati, ad esempio:

add_action( 'rest_api_init', function () {
    register_rest_route( 'rw-user/v1', '/log-in', array(
        'methods' => 'POST',
        'callback' => 'ajax_login',
    ));
    register_rest_route('rw-user/v1','/log-out', array(
        'methods' => 'POST',
        "callback" => 'ajax_logout'
    ));
     // .... truncated ....
});

Sono perplesso perché posso raggiungere questi endpoint con e senza NONCE (mi diverte perché sono inglese).

Se passo l'intestazione nonce, controlla il nonce ed esegue la funzione se ok, rifiuta se non ok. Se non passo l'intestazione nonce, non controlla il nonce, ma esegue comunque la funzione ...

Ho letto nella documentazione:

https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/

"Tieni presente che non è necessario verificare che il nonce sia valido all'interno del tuo punto finale personalizzato. Questo viene fatto automaticamente per te in"

Quindi, se l'endpoint sta già facendo la verifica, sicuramente dovrebbe fallire se non è presente nessun nonce?

Ciò significa che gli endpoint rest non controllano automaticamente la validità del nonce e dovrei verificare io stesso la validità all'interno della funzione?

Inoltre, alcune pagine utilizzano pesantemente AJAX per interagire con questi punti finali personalizzati. Con ogni richiesta AJAX, il nonce diventa non valido, interrompendo le future richieste AJAX (sto usando POST).

Ho pensato di dover generare un nuovo nonce nella funzione che riceve la richiesta AJAX e restituisce questo nuovo nonce al browser in modo da poter inserire il nuovo nonce nell'intestazione della successiva richiesta AJAX.

$new_nonce = wp_create_nonce( 'new_nonce' );
wp_send_json_success(array('nonce'=>$new_nonce ));

Posso vedere il nuovo nonce restituito nella mia console ... l'ho usato per aggiornare l'intestazione nella mia prossima richiesta - ma il nonce fallisce nonostante sia nuovo?

Qualche consiglio sul modo corretto di usare NONCES sarebbe molto apprezzato. Grazie!

Risposte

1 SallyCJ Nov 03 2020 at 02:53

Per limitare l'accesso all'endpoint dell'API REST, puoi utilizzare il permission_callbackparametro in questo modo:

register_rest_route( 'rw-user/v1', '/log-out', array(
    'methods'             => 'POST',
    'callback'            => 'ajax_logout',
    'permission_callback' => function () {
        return current_user_can( 'read' );
    },
) );

E ciò richiederà che l'utente corrente sia connesso a WordPress e anche all'API REST per accedere all'endpoint in example.com/wp-json/rw-user/v1/log-out.

Quindi, se l'endpoint sta già facendo la verifica, sicuramente dovrebbe fallire se non è presente nessun nonce?

Sì. Però,

Se non passo l'intestazione nonce, non controlla il nonce, ma esegue comunque la funzione ...

Questo perché il callback dell'endpoint viene sempre chiamato una volta che il callback delle autorizzazioni restituisce un true- e nota che, in WordPress 5.5 e versioni successive, dovresti sempre impostare il callback - puoi utilizzare __return_trueper consentire tutti gli accessi all'endpoint. Per esempio

register_rest_route( 'rw-user/v1', '/log-in', array(
    'methods'             => 'POST',
    'callback'            => 'ajax_login',
    'permission_callback' => '__return_true',
) );

Posso vedere il nuovo nonce restituito nella mia console ... l'ho usato per aggiornare l'intestazione nella mia prossima richiesta - ma il nonce fallisce nonostante sia nuovo?

Probabilmente è perché non stai inviando il nonce corretto.

  • L'azione nonce per autenticare l'utente corrente è wp_rest, quindi dovresti usare wp_create_nonce( 'wp_rest' )quando generi il (nuovo) nonce.

  • E assicurati di inviare il nonce tramite l' X-WP-Nonceheader (preferito) o il _wpnonceparametro data (che non è male, ma non molto affidabile).

Quindi, per quanto riguarda il fatto che " non è necessario verificare ", è vero solo per il wp_restnonce (ovvero l'autenticazione predefinita basata sui cookie). Tutti gli altri nonce, se ce ne fossero, devono essere verificati manualmente.