Websupporter

Vor allem über WordPress.

Nonces in der REST API

Wenn Du einfach mal schnell ein Nonce in der REST API von WordPress validieren möchtest kann es passieren, dass Du auf ein kleines Hindernis stößt. Ich hatte letztens ein kleines Script geschrieben, welches entweder über die admin-ajax.php läuft, wenn die REST API nicht vorhanden ist, ober aber über die REST API.

Schauen wir uns folgendes Script an, um das folgende Problem zu verdeutlichen:

Embed from gist.github.com

Click the button below to load the content from gist.github.com.

Wir registrieren also die Ajax Action für admin-ajax.php und eine neue Rest Route. Der Callback ajax_nonce_test() bereitet im Wesentlichen die Daten auf und führt dann auf nonce_test(), die Funktion, welche auch von der Rest Route /rest-api-nonces/v1/nonce-test aufgerufen wird.

Am Ende registrieren wir noch einen Shortcode, der uns nur schnell die Test-URLs ausgibt.

Soweit der Überblick. Zentral ist nun, was in nonce_test() passiert. Hier wird geprüft, ob das in $request['testnonce'] übergebene Nonce gültig ist. Wenn nicht wird „FALSE“ zurückgegeben, oder aber „TRUE“.

Jetzt zum Witz. Loggen wir uns ein, gehen auf die Seite und rufen die admin-ajax.php auf, so werden wir "TRUE" erhalten, über die REST API "FALSE". Whaaaat? Mehrere Sachen sollten hier beachtet werden:

  1. Die REST-API authentifiziert eine⋅n Benutzer⋅in anders als die admin-ajax.php.
  2. Um ein Nonce zu erstellen und zu verifizieren wird die User-ID herangezogen.

Ob ein⋅e Benutzer⋅in eingeloggt ist oder nicht, darüber entscheidet ein Cookie, welcher beim Einloggen hinterlegt wird. Passt der Cookie, sind wir eingeloggt. Geht die Nutzer⋅in auf die admin-ajax.php so ist er oder sie eingeloggt. Die REST API allerdings verwendet eine etwas umfangreichere Cookie-Authentifizierung. Hier genügt nicht ein einfaches Cookie, sondern dieses muss zusammen mit einem – Ironie der Geschichte – gültigen Nonce übergeben werden.

Basics der Authentifizierung in der REST API

In der WP_REST_Server gibt es eine check_authentication Methode, die eigentlich nur aus dem Filter rest_authentication_errors besteht. Wird über diesen Filter ein WP_Error-Objekt übergeben gilt eine Authentifizierung als gescheitert und wir erhalten ein „Du bist nicht berechtigt“-Response zurück. Über diesen Filter können also User-Authentifizierungen stattfinden.

Von Haus aus bringt WordPress die sogenannte „Cookie-Authentifizierung“ mit, welche in der rest_cookie_check_errors() stattfindet. Wenn der Prozess in diese Funktion rennt sind wir noch immer – über unseren Cookie – eingeloggt. Doch wenn das entsprechende Nonce nicht gefunden wird, werden wir zunächst ausgeloggt, bevor es – jetzt eben nicht mehr eingeloggt – weiter geht. Wird ein Nonce gefunden, welches allerdings den falschen Wert enthält, so wird ein WP_Error zurückgegeben und der Zugriff ganz geblockt.

Wenn wir also mit dem Codesnippet von oben schließlich in unserem nonce_test()-Callback ankommen, haben wir keine User-ID mehr, die es allerdings braucht, da das Nonce mit einer solchen ID erstellt wurde.

Wie funktioniert Cookie Authentifizierung in der REST API?

Statt also irgendwie willkürlich ein Nonce zu übergeben, welches dann im Callback geprüft wird (es mag Gründe dafür geben, aber in meinem Fall brauchte ich es nicht noch einmal), sollte also ein spezielles Nonce übergeben werden: wp_create_nonce( 'wp_rest' );. Und natürlich muss auch der Parameter stimmen. Das wp_rest Nonce kann entweder über den Parameter _wpnonce oder aber über den Request Header X-WP-Nonce. übergeben werden. Eine gute Einführung dazu findest Du auf der API Dokumentation.

Zurück zu meinem Beispiel

Für meine Zwecke genügte es also, über den _wpnonce Parameter zu gehen. Da das Nonce in der REST API automatisch schon geprüft wird, verschiebe ich die Nonce-Validierung in die Ajax-Funktion. So sieht mein überarbeiteter Code aus:

Embed from gist.github.com

Click the button below to load the content from gist.github.com.

Fazit

Wenn Du also irgendwo in Deinem Rest API Callback Nonces brauchst, achte darauf dass der Loginstatus der Nutzer⋅innen mit dem im Frontend überein stimmt. Vermutlich erledigt sich damit auch schon die Notwendigkeit für Dich, ein Nonce überhaupt zu benutzen, aber es mag Umstände geben, in denen es Sinn machen kann, auch im Callback Nonces zu validieren.

Über den Autoren

Seine erste Webseite hat David Remer 1998 in HTML verfasst. Wenig später war er fasziniert von DHTML und JavaScript. Nach jahrelanger Freelancerei arbeitete er zunächst für Inpsyde und ist heute Entwickler bei Automattic. Außerdem hat er das Buch "WordPress für Entwickler" verfasst.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.