WordPress REST-API – Schnittstelle deaktivieren, anpassen und individualisieren
Die REST-API von WordPress bietet vielfältige Möglichkeiten Inhalte auszulesen und an externe Apps oder Sites zu übergeben. Mit ein paar Anpassungen kann die Schnittstelle vollständig oder teilweise deaktiviert werden.
Die REST-API von WordPress stellt die Inhalte einer Website über eine spezifische Adresse in strukturierter Form (JSON) öffentlich zur Verfügung. Mit kurzen Code-Beispielen zeigen wir euch, wie ihr die Bereitstellung der Websiteinhalte auf diesem Wege deaktivieren, nach euren Wünschen modifizieren oder vollständig individualisieren könnt.
Wozu dient die WP-REST-API?
Die REST-API von WordPress ist u.a. dann hilfreich, wenn die Inhalte einer WP-Installation an eine andere Website oder Anwendung übergeben werden sollen. Bei der Umsetzung der Website für das Theater Thikwa in Berlin, haben wir beispielsweise die Möglichkeiten der WP-REST-API genutzt, um den Theater-Spielplan automatisiert an die Plattform Berlin Bühnen zu übertragen.
WP-REST-API vollständig deaktivieren
Sollen externe Zugriffe auf die Inhalte einer Website grundsätzlich nicht möglich sein, z. B. um Inhaltsdiebstahl vorzubeugen oder das Angriffsrisiko durch Verschleierung möglicher Einfallstore zu vermindern, kann die API einfach deaktiviert werden. Wenn ihr euch sicher seid, dass ihr die REST-API nicht benötigt, könnt ihr das Feature einfach mittels zweier Filter vollständig abschalten.
add_filter('rest_enabled', '_return_false');
add_filter('rest_jsonp_enabled', '_return_false');
Für aktuelle WordPress-Installationen ist dieses Vorgehen jedoch nicht immer ratsam. Der Block-Editor (Gutenberg) von WordPress ist von der Schnittstelle abhängig und benötigt deshalb unbedingt Zugriff auf diese. Ohne die REST-API funktioniert der WordPress-Editor nicht mehr. Aus diesem Grund solltet ihr sicher stellen, dass die API im Redaktionsbereich funktioniert und nur für externe Besucher im Frontend deaktiviert ist. Dafür könnt ihr diesen Filter verwenden:
add_filter('rest_authentication_errors', function($result) {
if (!is_user_logged_in()) {
return new WP_Error('rest_API_cannot_access', array( 'status' => rest_authorization_required_code()));
return $result;
}
});
Einzelne Endpoints deaktivieren
Standardmäßig werden alle Inhalte einer WordPress-Standard-Installation in der API verfügbar gemacht. In manchen Fällen ist es sinnvoll, nicht die ganze API von WordPress zu deaktivieren, sondern nur einzelne Endpunkte. So kann man zum Beispiel die Inhalte von Posts, Pages und Comments in der API belassen, aber, etwa in in Hinblick auf Sicherheit der Website, die Infos zu den Website-Einstellungen sowie allen registrierten Benutzer aus dieser entfernen. Das funktioniert über den Filter rest_endpoints
.
Das folgende Beispiel deaktiviert die API-Endpunkte für Benutzernamen und Einstellungen. Diese Informationen sind folglich nicht mehr in der API zu finden.
add_filter('rest_endpoints', function ($endpoints) {
$endpoints_to_remove = array(
'users',
'settings'
);
foreach ($endpoints_to_remove as $endpoint) {
$base_endpoint = "/wp/v2/{$endpoint}";
foreach ($endpoints as $maybe_endpoint => $object) {
if (strpos($maybe_endpoint, $base_endpoint) !== false) {
unset($endpoints[$maybe_endpoint]);
}
}
}
return $endpoints;
});
URL-Prefix ändern
Ein weitere Möglichkeit, die API den eigenen Bedürfnissen anzupassen, ist die Änderung des Standard-Präfixes wp-json
in einen beliebigen Präfix. Das ermöglicht die Individualierung der API-Route und sorgt nebenbei dafür, dass die Standardroute dann keine Inhalte mehr liefert, was unerwünschte Zugriffe von außen zumindest erschwert. Über den Filter rest_url_prefix
ist die Anpassung leicht gemacht.
add_filter('rest_url_prefix', function () {
return 'data';
});
Die Standardroute für API-Anfragen wird damit von https://example.com/wp-json/wp/v2/
in https://example.com/data/wp/v2/
geändert.
Eigene Routes und Endpoints definieren
Wenn ihr andere oder anders strukturierte Informationen aus der Website über die Schnittstelle zur Verfügung stellen wollt, müssen eigene Endpoints dafür angelegt werden sowie eine Callback-Funktion, die die Daten zur Verfügung stellt. Das kann zum Beispiel notwendig sein, wenn Daten der eigenen Website in ein externes System übertragen werden sollen, dessen eigene API die Daten in einer spezifischen Struktur übermittelt bekommen möchte.
Über den oben bereits erwähnten Filter rest_endpoints
fügt ihr der API eine neue Route hinzu, der dann über die Action rest_api_init
ein neuer Endpunkt angehängt wird.
add_filter('rest_endpoints', function ($endpoints) {
$custom_route = 'custom'; // allowed custom route
foreach ($endpoints as $endpoint => $details) {
if (!fnmatch('/' . $custom_route . '/*', $endpoint, FNM_CASEFOLD)) {
unset($endpoints[$endpoint]);
}
}
return $endpoints;
});
add_action('rest_api_init', function () {
register_rest_route('custom', 'endpoint', array(
'methods' => 'GET',
'callback' => 'custom_endpoint'
));
});
Wenn zuvor der REST-URL-Prefix, wie oben beschrieben, in data
geändert wurde, steht euch euer Endpoint nun unter https://example.com/data/custom/endpoint/
zur Verfügung. Daten sind unter der Adresse so aber noch nicht zu sehen. Dafür benötigt ihr einen Callback, der die gewünschten Informationen aus der Datenbank holt und in der gewünschten Form aus gibt.
function custom_endpoint() {
$endpoint = new stdClass;
$endpoint->query = new WP_Query(array(
'post_type' => 'page',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
));
if ($endpoint->query->have_posts()) {
while ($endpoint->query->have_posts()) {
$endpoint->query->the_post();
$endpoint->output[] = array(
'id' => get_the_ID(),
'title' => get_the_title(),
'excerpt' => get_the_excerpt(),
'url' => get_the_permalink()
);
}
}
return rest_ensure_response($endpoint->output);
}
In dem Beispiel werden alle Pages aus der Datenbank abgefragt und deren ID, Titel, Auszug sowie URL in einem verschachtelten Array hinterlegt. Mit der Funktion rest_ensure_response()
werden die Informationen in dem Array dann in JSON gewandelt. In dieser Form stehen die Daten dann am zuvor definierten Endpunkt https://example.com/data/custom/endpoint/
zur Verfügung.
Auf diese Weise kann die API-Antwort beliebig angepasst werden und bietet vielfältige Möglichkeiten bei der Bereitstellung von öffentlichen Daten einer WordPress-Instanz.
Alle in diesem Beitrag verwendeten Code-Beispiele müssen in die functions.php-Datei eures Themes integriert oder in Plugins auslagert werden.
Grüß Gott Konstantin, das wordpress rest API Thema scheint aktuell zu sein und es gibt bis jetzt nirgends eine Erklärung, die über die gängigen Lösungen hinausgeht. Ich bei 1und1 NOCH einen alten managed apache server – kam wegen Betreuungsthemen älter Menschen in den letzten beiden Jahren nicht zum Umzug in ein neues Paket mit aktuellen Versionen der MySQL Datenbanken. Obwohl ALLES in den letzten Jahren einwandfrei funktioniert hat, hat es mich jetzt bei allen Seiten mit dem gleichen Rest API Problem erwischt und trotz der gängigen Schritte 1 – 4 SSL Prüfung -siehe diesen Link – bleibt das Problem bestehen ….
https://www.wpbeginner.com/wp-tutorials/how-to-fix-curl-error-28-connection-timed-out-after-x-milliseconds/
Die Seiten stehen alle auf 256 MP Speicher – die aber auf Qualys Bericht zur teilweise umgesetzt werden.
Punkt 5: Bitten sie den Hosting Anbieter – hier ionos – um Hilfe – aber das dauert …
Wegen ‚Bestellungs-Stopp‘ seit 3 Tagen habe ich bestimmt 20 Stunden mit Recherche verbracht ….
Die Seiten werden – wenn keine Servertraffic vorhanden ist noch zügig aufgerufen. Spätesten mti dem Login hängt es: Antwortzeit über 30 Sekunden und beim Nächsten Prozess heißt es dann: Error 500 – Internal server error Aktiviere ich dann diese url 2 bis 3 mal, taucht die Seite schließlich auf ….
Bei allen Seiten lautet dann die Fehlermeldung im Website Zustand:
Beim Testen des REST-API ist ein Fehler aufgetreten:
REST-API-Endpunkt: https://www.kupfer-anton.de/wp-json/wp/v2/types/post?context=edit
REST-API-Antwort: (http_request_failed) cURL error 28: Operation timed out after 10000 milliseconds with 0 bytes received
Ich nutze Divi und immer Child-Themes – mit den hier genannten Einfügungen bin ich auch nicht weitergekommen ….
Hattest Du dieses Thema schon einmal bzw. fällt Dir dazu spontan eine Lösung / Möglichkeit ein?
Würde mit sehr über einen Tipp / Lösungsansatz freuen, der die Ladezeiten sofort senkt, Bestellungen wieder möglich macht und dann in Ruhe den Umzug auf ein aktuelles Paket ermöglicht.
Herzlichen Dank – Hans Hubert
Hallo Konstantin,
großartiger Post! Tatsächlich scheint bei deaktivierter WordPress REST-API (ich nutze das Plugin „Disable WP REST API“ von Jeff Starr) keine der aktuellen Consent-Lösungen mehr zu funktionieren (z.B. Borlabs Cookie, Complianz, Real Cookie Banner). Das ist sehr ärgerlich, da es bisher mit ajax super funktioniert hat, vor allem die Ausgabe der Daten (per HTML) in der Datenschutzerklärung über Shortcodes (z.B. mit dem alten Borlabs Cookie v2, das leider nicht mehr aktualisiert wird). Warum jetzt ajax als unsicher und die REST-API als sicher eingestuft wurde, ist für mich nicht nachzuvollziehen, so sind doch schon Angriffe über die REST-API bekannt geworden.
Kannst du mir (kostengünstig) helfen, die neue Version von Borlabs Cookie (v3), die ich leider schon gekauft habe, mit entsprechenden REST-API Befehlen in der functions.php im Child-Theme so zu konfigurieren, dass noch eine möglichst hohe Sicherheit für meine Website gegeben ist?
Alternativ: Kennst du eine aktuelle Consent-Lösung, die keinen Zugriff auf die REST-API / Json benötigt?
Aktuell habe ich wg. o.g. Probleme die bisherigen o.g. Consent-Lösungen alle wieder von meiner Website runtergeschmissen und weiß nicht weiter.
LG Namira
Hallo Namira, wir verwenden üblicherweise auch Borlabs Cookie als Consent-Lösung. Die neue Version 3.0 hat erst vor wenigen Tagen die Beta-Phase verlassen, daher setzen wir diese Version noch nicht produktiv ein. Ich habe keine fertige Lösung für das beschriebene Problem. Ein Ansatz wäre aber, die REST-API von WordPress nicht komplett abzuschalten, sondern nur kritische Endpunkte, wie im Beitrag beschrieben. Sobald wir eine zuverlässige Methode zur Lösung des Problems haben, werden wir diese hier beschreiben.
Habe ein ähnliches Problem mit „Real Cookie Banner“. Dieses behauptet, die WP REST API-Route https://example.com/wp-json/real-cookie-banner/v1/consent wäre gesperrt oder so. Daher wäre die Speicherung der Nutzer-Einstellungen im Cookiebanner nicht möglich. Sind die aber.
Der WP Zustand meldet ähnliches:
Beim Testen des REST-API wurde ein unerwartetes Ergebnis zurückgegeben:
REST-API-Endpunkt: https://example.com/wp-json/wp/v2/types/post?context=edit
REST-API-Antwort: (404) Not Found
100%-ig gibt es nichts auf der Site, welches die API blockiert. Weder eins der Plugins, noch so ein Script, noch vonseiten des Hosts. Auch mit Standard-Theme, ohne Plugins: Detto, Fehler bleibt.
Okay, die Site und deren Administration funktioniert einwandfrei – doch die Meldung nervt.
Was nun?
Gibts evtl. ein Script, mit dem man das irgendwie herausfinden kann, wo es hakt?
Hallo Konstantin,
wie findest Du die folgende Lösung?
Ich habe mal einfach im Domain-Root-Ordner den Ordner „wp-json“ angelegt und den Zugriff in der .htaccess verboten.
Schöne Grüße
Niko
Hallo Niko, interessante Lösung. Gut, wenn das für dich so funktioniert.
Hallo,
danke für den Artikel. Ich bin noch neu bei WordPress, deshalb folgende Frage: In welcher wp Datei kann ich denn die oben genannten Funktionen implementieren?
Viele Grüße
Hallo Anton, du kannst die Code-Beispiele in die functions.php-Datei deines Themes integrieren oder in Plugins auslagern. Der Artikel wurde entsprechend ergänzt. Vielen Dank und beste Grüße