Safety first: AJAX-Anfragen mit Nonce absichern!

Nonce ist gemäss WordPress eine «einmalig verwendete Zeichenkette», die dazu dient, URLs und Formulare vor Missbrauch zu schützen. Es handelt sich um einen cleveren Hash aus Zahlen und Buchstaben, der als WordPress-Nonce bezeichnet wird. Hier kommt der Clou: Nonce wird nur einmal verwendet und hat eine begrenzte Lebensdauer.

Jetzt kommt der interessante Teil: Ich werde dir im Folgenden zwei verschiedene Methoden vorstellen, mit denen du eine AJAX-Anfrage mit Nonce sicher machen kannst. Das bedeutet, dass du dir keine Sorgen mehr um unerwünschte Zugriffe machen musst. Bist du bereit, in die Welt der Nonce-Sicherheit einzutauchen? Los geht’s!

1. Nonce zum DOM hinzufügen

Zuerst fügen wir unsere js-Datei korrekt mit wp_enqueue_script() hinzu:

 function ud_theme_name_scripts() {
     wp_enqueue_script( 'script-name', get_stylesheet_directory_uri().
         '/js/ajax-file.js', array(), '1.0.0', true );
 }
 add_action( 'wp_enqueue_scripts', 'ud_theme_name_scripts' );

Bei dieser Methode schreiben wir Nonce in das DOM und lesen den Schlüssel später mit jQuery wieder aus. Der dafür verwendete Container soll im Footer erscheinen, dafür wird der Hook wp_footer verwendet:

function ud_add_nonce() {
  /* Nonce erzeugen */
  $nonce = wp_create_nonce( 'ud-ajax-nonce' );
  /* Leerer div-Container mit data-Attribut ausgeben */
  echo '<div id="ud-nonce" data-nonce="' . esc_attr( $nonce ) . '"></div>';
}
add_action('wp_footer', 'ud_add_nonce');

Der erzeugte Nonce-Schlüssel wird als Attribut des Elements #ud-nonce in das DOM eingefügt. Das data-Attribut wird bei der AJAX-Anfrage mit jQuery( '#ud-nonce' ).data( 'nonce' ) übergeben:

$.ajax({
  type: "POST",          // use $_POST request to submit data
  url: ud_ajax_url,      // URL to "wp-admin/admin-ajax.php"
  data: {
    action: 'ud_ajax_callback', // wp_ajax_*, wp_ajax_nopriv_*
    security: jQuery( '#ud-nonce' ).data( 'nonce' ), // PHP: $_POST['security']
    vorname: 'ulrich', // PHP: $_POST['vorname']
    nachname: 'digital', // PHP: $_POST['nachname']
  },
  success:function( data ) {
    $( '#ulrichdigital' ).html( data );
  },
  error: function() {
    console.log(errorThrown); // error
  }
});

Der Schlüssel wird übertragen und kann im AJAX-Callback mit wp_verify_nonce( $_POST['security'], 'ajax_nonce' ); überprüft werden:

/**
 * Ajax Callback
 */
function ud_ajax_callback(){
 
  /* Nonce prüfen */
  if ( ! wp_verify_nonce( $_POST['security'], 'ajax_nonce' ) ) {
    wp_die( 'Nonce ist ungültig!' );
  } // endif

  /* Get request */
  $vorname = isset( $_POST['vorname'] ) ? $_POST['vorname'] : 'N/A';
  $nachname = isset( $_POST['nachname'] ) ? $_POST['nachname'] : 'N/A';
  
  echo '<p>Hello. Dein Vorname ist ' . strip_tags( $vorname ) . '.</p>';
  echo 'Dein Nachame ist ' . strip_tags( $nachname ) . '.</p>';
  
  wp_die(); // benötigt um die AJAX-Anfrage zu beenden
}

Wir verwenden wp_ajax_nopriv_ und wp_ajax_ um die Funktion mit den WordPress-Hooks zu verbinden:

 add_action('wp_ajax_nopriv_ud_ajax_callback', 'ud_ajax_callback');    
 add_action('wp_ajax_ud_ajax_callback', 'ud_ajax_callback');

Der Hook wp_ajax_ud_ajax_callback wird ausgelöst, wenn ein Benutzer eingeloggt ist, und wp_ajax_nopriv_ud_ajax_callback, wenn er es nicht ist.

2. Nonce über Localize Script hinzufügen

Die zweite Methode ist per wp_localize_script(). Diese Funktion erlaubt es auch einen Array zu übergeben.

Wir verwenden demnach wp_localize_script(), um Nonce einen Schlüssel zu übergeben:

add_action( 'wp_enqueue_scripts', 'ud_ajax_script' );
 
function ud_ajax_script() {
  wp_register_script( 'ud-wp-ajax-script', get_stylesheet_directory_uri() . "js/ud-ajax-script.js", array( 'jquery' ), '1.0.0', true );
 
  /* Skript-Daten lokalisieren */
  $ud_ajax_data = array(
    'url'   => admin_url( 'admin-ajax.php' ),
    'nonce' => wp_create_nonce( 'ud-ajax-nonce' ),
  );
 
  /* Daten als JS var über Localize Script senden */
  wp_localize_script( 'ud-ajax-script', 'ud_ajax_data', $ud_ajax_data  );
}

Damit ist das Skript erfolgreich registriert und lokalisiert. Bei der AJAX-Anfrage bekommt security mit ud_ajax_data.nonce den erzeugten Schlüssel mit:

$.ajax({
    type: "POST",                        // use $_POST request to submit data
    url: ud_ajax_data.url,               // URL to "wp-admin/admin-ajax.php"
    data: {
        action     : 'ud_sayhello',      // wp_ajax_*, wp_ajax_nopriv_*
        security   : ud_ajax_data.nonce,
        vorname    : 'ulrich',           // PHP: $_POST['vorname']
        nachname   : 'digital',          // PHP: $_POST['nachname']
    },
    success:function( data ) {
        $( '#ud-callback' ).html( data );
    },
    error: function(){
        console.log(errorThrown); // error
    }
});

Im Callback wird der Schlüssel mit wp_verify_nonce geprüft und mit «erwischt!» beendet, falls die Schlüssel nicht übereinstimmen:

// Check for nonce security      
if ( ! wp_verify_nonce( $_POST['security'], 'ajax-nonce' ) ) {
  wp_die ( 'erwischt!');
}

Der Rückgabewert (int|false) der Funktion ist im Übrigen wie folgt:
1 wenn Nonce gültig ist und vor 0-12 Stunden erzeugt wurde
2 wenn Nonce gültig ist und vor 12-24 Stunden erzeugt wurde
false wenn Nonce ungültig ist

1 Star2 Stars3 Stars4 Stars5 Stars (1)

Deine Meinung ist uns wichtig! Auch wenn du denkst, dass unser Beitrag so spannend wie eine Präsentation über die Vorteile von Kalkulationstabellen ist, teile es uns mit!

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert