wp_nonce_field în WordPress

Securitate WordPress 2.0.4

Adaugă într-un formular un câmp ascuns cu un nonce, un cod care dovedește că cererea pornește chiar de pe site-ul tău.

Sintaxă
wp_nonce_field( int|string $action = -1, string $name = '_wpnonce', bool $referer = true, bool $display = true ): string
wp_create_nonce( string|int $action = -1 ): string
wp_verify_nonce( string $nonce, string|int $action = -1 ): int|false

Ce face wp_nonce_field

Un nonce este un cod scurt (10 caractere), legat de o acțiune, de utilizatorul curent și de sesiunea lui, valabil în mod obișnuit 24 de ore. Protejează împotriva CSRF: alt site nu poate trimite în numele tău un formular care șterge sau modifică date, pentru că nu cunoaște nonce-ul. wp_nonce_field() (din 2.0.4) afișează câmpul ascuns, wp_create_nonce() (din 2.0.3) doar generează codul, iar wp_verify_nonce() (din 2.0.3) îl verifică.

wp_nonce_field() scrie un <input type="hidden"> cu id și name egale cu $name (implicit _wpnonce) și, dacă $referer este true, încă un câmp ascuns _wp_http_referer cu adresa paginii curente. Cu $display = false doar întoarce HTML-ul, fără să îl afișeze.

wp_verify_nonce() întoarce 1 dacă nonce-ul a fost generat în ultimele 0-12 ore, 2 pentru 12-24 de ore și false dacă e invalid. Nonce-ul nu verifică drepturile: îl combini mereu cu current_user_can(). În paginile de administrare, check_admin_referer() face verificarea și oprește cererea automat.

Parametri

Parametru Descriere
$action Numele acțiunii protejate, de exemplu 'dex_salveaza_setari'. Folosește același nume la generare și la verificare.
$name Numele câmpului ascuns (și cheia din $_POST). Implicit '_wpnonce'.
$referer Adaugă și câmpul _wp_http_referer. Implicit true.
$display true afișează câmpurile; în ambele cazuri funcția întoarce HTML-ul.
$nonce La wp_verify_nonce(): codul primit din formular sau din URL.

Ce returnează

wp_nonce_field() întoarce HTML-ul câmpurilor; wp_create_nonce() întoarce codul (șir de 10 caractere); wp_verify_nonce() întoarce 1, 2 sau false.

Exemple

Exemplul 1: Câmpul nonce într-un formular de setări

Cu nume propriu (dex_nonce) apar două câmpuri ascunse: nonce-ul și adresa paginii. Codul nonce diferă pe fiecare site și pentru fiecare utilizator.

<?php
?>
<form method="post" action="">
    <?php wp_nonce_field( 'dex_salveaza_setari', 'dex_nonce' ); ?>
    <input type="text" name="dex_oras" value="Iași">
    <button type="submit">Salvează</button>
</form>

Ce afișează pagina

<form method="post" action="">
    <input type="hidden" id="dex_nonce" name="dex_nonce" value="3f9a1c7b2e" /><input type="hidden" name="_wp_http_referer" value="/wp-admin/admin.php?page=dex-setari" />    <input type="text" name="dex_oras" value="Iași">
    <button type="submit">Salvează</button>
</form>

Exemplul 2: Verificarea cu wp_verify_nonce()

Verificăm nonce-ul și dreptul utilizatorului înainte de a salva. Valoarea din $_POST trece prin wp_unslash() și sanitize_text_field().

<?php
function dex_proceseaza_setari() {
    if ( ! isset( $_POST['dex_nonce'] ) ) {
        return;
    }
    $nonce = sanitize_text_field( wp_unslash( $_POST['dex_nonce'] ) );
    if ( ! wp_verify_nonce( $nonce, 'dex_salveaza_setari' ) ) {
        wp_die( 'Cererea nu a putut fi verificată.' );
    }
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( 'Nu ai dreptul să modifici setările.' );
    }
    update_option( 'dex_oras', sanitize_text_field( wp_unslash( $_POST['dex_oras'] ?? '' ) ) );
}
add_action( 'admin_init', 'dex_proceseaza_setari' );

Exemplul 3: wp_create_nonce() și wp_verify_nonce() încercate din terminal

Cu wp eval, ca utilizatorul ana: generăm un nonce, îl verificăm pentru aceeași acțiune (1 = valid, generat în ultimele 12 ore) și pentru altă acțiune (false).

wp eval '$n = wp_create_nonce( "dex_rezervare" ); echo $n, " ", wp_verify_nonce( $n, "dex_rezervare" ), " "; var_export( wp_verify_nonce( $n, "dex_alta" ) );' --user=ana

Ieșire în terminal

8b41d0e6fa 1 false

Greșeli frecvente

  • Să folosești nonce-ul în loc de verificarea drepturilor: un nonce valid arată doar că cererea vine din formularul tău, nu că utilizatorul are voie. Adaugă current_user_can().
  • Nume de acțiune diferite la generare și la verificare ('dex_salveaza' vs. 'dex_salveaza_setari'): verificarea eșuează mereu.
  • Să lași $action implicit (-1): toate formularele ar folosi același nonce. Dă fiecărei acțiuni un nume propriu, eventual cu ID-ul elementului.
  • Pagini cache-uite care conțin nonce-uri: după 24 de ore vizitatorii primesc un nonce expirat și formularul nu mai funcționează.

Comenzi înrudite

  • check_admin_referer: Verifică nonce-ul unei cereri din administrare și oprește execuția cu o pagină de eroare dacă e invalid sau a expirat.
  • current_user_can: Verifică dacă utilizatorul conectat are un anumit drept (capability), de exemplu manage_options sau edit_post pentru un articol.
  • sanitize_text_field: Curăță textul de pe o singură linie primit de la utilizator: elimină HTML-ul, rândurile noi, tab-urile și spațiile în plus.