In einem aktuellen Projekt verwenden wir WordPress als Backend für eine native Mobile App. Die App selbst wird von einer anderen Agentur entwickelt. Ich bin für den WordPress-Teil zuständig. Der Inhalt der App wird über mehrere Custom-Post-Types und Custom-Taxonomies sowie einiger spezieller Blocks erstellt, für eine komfortable Verwaltung. Die App kann ohne Registrierung verwendet werden. Für erweiterte Funktionen, wie etwas die Synchronisation der Ergebnisse mit mehreren Geräten oder der Vergleich mit anderen, wird eine Registrierung benötigt.
Der Server für den Empfang von Requests vorbereiten
Um Anfragen von der App an den Server machen zu können, müssen einige Response-Header geschickt werden, damit diese akzeptiert werden. Die gilt besonders für die iOS-Version der App. Ich habe zuerst versucht die Header über die Server-Konfiguration umzusetzen, nur um dann festzustellen, dass einige davon zusätzlich noch von WordPress gesetzt wurden. Das Resultat waren dann doppelte Header mit gleichen Namen aber unterschiedlichen Werten. Nach ein wenig Debugging konnte ich ein paar Hooks finden, die ich verwenden konnte:
function app_rest_headers_allowed_cors_headers( $allow_headers ) {
return array(
'Origin',
'Content-Type',
'X-Auth-Token',
'Accept',
'Authorization',
'X-Request-With',
'Access-Control-Request-Method',
'Access-Control-Request-Headers',
);
}
add_filter( 'rest_allowed_cors_headers', 'app_rest_headers_allowed_cors_headers' );
Bei einem anderen Hook gab es leider keinen Filter, daher musste ich hier direkt die header()
Funktion aufrufen:
function app_rest_headers_pre_serve_request( $value ) {
header( 'Access-Control-Allow-Origin: *', true );
return $value;
}
add_filter( 'rest_pre_serve_request', 'app_rest_headers_pre_serve_request', 11 );
Nach dieser kleinen Vorbereitung können wir versuchen über den Users-Endpoint zu erstellen. Das wird aber nicht funktionieren. Wieso nicht? Nun, ganz einfach aus dem Grund, dass man nicht einfach über die WordPress REST API einen Benutzer erstellen kann, ohne sich vorher zu autorisieren. Wenn das möglich wäre könnte ja sonst jemand auf einer beliebigen WordPress-Seite Benutzer erstellen.
Einen Nutzer mit der REST API authentifizieren
Wie müssen uns also an der REST API authentifizieren, aber wie machen wir das? Es gibt hier verschiedene Möglichkeiten. Eine neue Möglichkeit, die als erstes im Core langen wird und kurz vor der Aufnahme steht sind die Application Password.
Es gibt schon einen Vorschlag für die Integration des Feature-Projects in WordPress 5.6. Wenn ihr aber jetzt schon diese Möglichkeit testen wollt, könnt ihr einfach das Plugin Application Passwords installieren.
Einen Benutzer für die Benutzerverwaltung erstellen
Normalerweise können nur Administratoren die Benutzer verwalten. Aber ihr möchtet vermutlich nicht unbedingt einer App sämtliche Berechtigungen geben, die ein Admin auf einer WordPress-Seite hat. Daher macht es Sinn, einen speziellen Benutzer zu erstellen, der nur die Berechtigungen hat, die für die Benutzerverwaltung benötigt werden. Ihr könnt das mit einem Plugin wie etwa Members machen, oder aber ihr erstellt die Rolle und den Benutzer mit PHP Code oder ihr verwendet die WP-CLI:
wp role create app App --clone=subscriber
wp cap add app create_users
wp user create app-rest-user app-rest-user@example.com --role=app
Der Benutzer braucht mindestens die Berechtigung create_users
, um Benutzer anlegen zu können. Wenn ihr zusätzlich die read
Berechtigung setzt, könnt ihr euch auch mit diesem Benutzer anmelden und das Application Password setzen (daher wird in dem Beispiel oben auch die Rolle subscriber
geklont). Alternativ könnt ihr als Admin das Application Password für einen Benutzer setzen.
Das Application Passwort für den neuen Benutzer erstellen
Nachdem ihr den Nutzer erstellt habt, könnr ihr euch mit diesem einloggen und auf die Profileinstellungen gehen (oder eben das Profil des Nutzers mit dem Admin bearbeiten). Hier findet ihr ein neues Feld, in dem ihr Application Passwords erstellen könnt. Wählt hier einen Namen aus und klickt auf „Add new“ (zum Zeitpunkt der Veröffentlichung des Beitrags gab es noch keine Übersetzung für das Plugin bzw. die Core-Funktionalität):
Daher öffnet sich ein Modal mit dem generierten Application Password. Ihr müsst dieses Passwort hier kopieren, da es nach dem Schließen des Modal nicht mehr als Klartext angezeigt werden kann.
Damit ist jetzt alles vorbereitet um einen Benutzer über einen Request an die REST API zu erstellen.
Deinen ersten Benutzer erstellen
Je nachdem welches System ihr verwendet, um Requests an die WordPress REST API zu schicken, sieht der Workflow hier anders aus. Daher zeige ich es heir am Beispiel eines curl
Requests über die Kommandozeile:
curl --user "app-rest-user:younfj4FX6nnDGuv9EwRkDrK" \
-X POST \
-H "Content-Type: application/json" \
-d '{"username":"jane","password":"secret","email":"jane@example.com"}' \
http://example.com/wp-json/wp/v2/users
Wenn ihr zuvor alles richtig eingerichtet habt, dann solltet ihr eine JSON-Response mit den Daten zum neuen Benutzer erhalten.
Fazit
Die Verwaltung von Benutzern ist nach etwas Vorbereitung und (aktuell) noch externer Plugins möglich. Es wird durch das neue Applications Passwords Core-Feature aber um einiges leichter. In gleicher Weise könnt ihr dann natürlich auch andere REST API Requests machen, die einen autorisierten Benutzer erfordern. Für eine erhöhte Sicherheit solltet ihr hierzu aber immer einen speziellen Benutzer erstellen (es sei denn, ihr wollte Inhalte für einen bestehenden Benutzer erstellen und zuweisen).
Disclaimer
Seit fast genau vier Jahren versuche ich all meine Beiträge geschlechtsneutral zu schreiben. Das ist mir bisher auch recht gut gelungen (auch wenn ich sicher doch mal aus Versehen etwas übersehen habe).
Im Englischen ist es bei Personenbezeichnungen auch recht einfach, da es hier nur selten eine männliche und weibliche Form gibt. In der deutschen Übersetzung verwende ich einfach statt einer Personenbezeichnung einen andren Begriff. Dadurch ist der Satz meisten genauso einfach lesbar, manchmal sogar besser. Aber beim heutigen Beitrag habe ich mich aber für „Benutzer“ und „Benutzerverwaltung“ entschieden. Ich hätte zwar auch „Zugang“ und „Zugangsverwaltung“ verwenden können, aber damit hätte ich wohl einige von euch sehr verwirrt. Der Terminus im Core ist aktuell eben noch „Benutzer“ und daher musste ich heute mal diese Ausnahme machen. Ich hoffe meine treuen Leserinnen verzeihen es mir 🙂