WP REST API Kennwort für GET-Endpunkt erforderlich

8

Ich habe einen benutzerdefinierten Beitragstyp card, den ich über die WP REST-API verfügbar mache. Gibt es eine Möglichkeit, eine Authentifizierung mit Cookie oder Basic Auth-Header zu verlangen? Ich sehe ein Argument unter dem POST-Methodenblock für das Passwort, bin mir aber nicht sicher, wie ich es verwenden soll.

Geben Sie hier die Bildbeschreibung ein

YarGnawh
quelle

Antworten:

9

Wenn wir eine Ruhe-Route mit registrieren register_rest_route(), können wir den permission_callbackParameter mit der gewünschten Berechtigung verwenden.

Überprüfen Sie beispielsweise, wie WP_REST_Posts_Controller::register_routes()und WP_REST_Users_Controller::register_routes()implementieren Sie den Berechtigungsrückruf.

Das Passwortargument, auf das Sie sich beziehen, ist das Passwort des Inhalts, das Sie für jeden Beitrag festlegen können und das nicht dasselbe ist.

Da Sie jedoch auf vorhandene Routen abzielen möchten, wie z.

/wp/v2/cards
/wp/v2/cards/(?P<id>[\d]+)
/wp/v2/cards/...possibly some other patterns...

Sie können beispielsweise den rest_dispatch_requestFilter verwenden, um Ihre zusätzliche Berechtigungsprüfung für diese Art von Routen einzurichten.

Hier ist ein Demo-Plugin:

add_filter( 'rest_dispatch_request', function( $dispatch_result, $request, $route, $hndlr )
{
    $target_base = '/wp/v2/cards';    // Edit to your needs

    $pattern1 = untrailingslashit( $target_base ); // e.g. /wp/v2/cards
    $pattern2 = trailingslashit( $target_base );   // e.g. /wp/v2/cards/

    // Target only /wp/v2/cards and /wp/v2/cards/*
    if( $pattern1 !== $route && $pattern2 !== substr( $route, 0, strlen( $pattern2 ) ) )
        return $dispatch_result;

    // Additional permission check
    if( is_user_logged_in() )  // or e.g. current_user_can( 'manage_options' )
        return $dispatch_result;

    // Target GET method
    if( WP_REST_Server::READABLE !== $request->get_method() ) 
        return $dispatch_result;

    return new \WP_Error( 
        'rest_forbidden', 
        esc_html__( 'Sorry, you are not allowed to do that.', 'wpse' ), 
        [ 'status' => 403 ] 
    );

}, 10, 4 );

Hier zielen wir auf die Routen /wp/v2/cardsund /wp/v2/cards/*GET ab, mit zusätzlichen Benutzerberechtigungsprüfungen.

Beim Debuggen mit der WordPress-Cookie-Authentifizierung können wir es zB direkt testen mit:

https://example.tld/wp-json/wp/v2/cards?_wpnonce=9467a0bf9c

woher der Nonce-Teil generiert wurde wp_create_nonce( 'wp_rest' );

Hoffe das hilft!

Birgire
quelle
Ich habe versucht, es für eine bestimmte Zielbasis allgemein zu machen, aber vielleicht gibt es einen einfacheren Weg, dies zu umgehen? Ich habe ein Funktionsbeispiel als Inline-Kommentar @MarkKaplun
birgire
Vielleicht ist es sogar noch einfacher, den Endpunkt für einen bestimmten benutzerdefinierten Beitragstyp zu entfernen, wobei der register_post_type_argsFilter und z. B. $args['show_in_rest'] = is_user_logged_in();für einen bestimmten Beitragstyp festgelegt sind oder auf basieren $args['rest_base']. Ich
bin
3

Das angezeigte Feld "Kennwort" bezieht sich nicht auf die REST-API, sondern auf den Post-Eintrag. Einzelne Beiträge in WordPress können passwortgeschützt sein, sodass Sie das Passwort benötigen, um ihren Inhalt zu sehen.

Diese Form des individuellen Post-Passworts ist kein starker Passwortmechanismus, sondern ein gemeinsames Passwort. Das Passwort ist für alle Benutzer gleich und wird unverschlüsselt und unverschlüsselt in der Datenbank gespeichert. Es war niemals als sicherer Mechanismus gedacht, es ist ein einfacher Mechanismus, um Inhalte auf einfache Weise zu verbergen.

Wenn Sie diesen Mechanismus mit der REST-API verwenden möchten, ist dies möglich. Wenn die ID des einzelnen Posts beispielsweise 123 lautet, kann ein Post folgendermaßen abgerufen werden:

http://example.com/wp-json/wp/v2/posts/123

Wenn dieser Beitrag kennwortgeschützt ist, wird er von dieser URL abgerufen:

http://example.com/wp-json/wp/v2/posts/123?password=example-pass

Referenz: https://developer.wordpress.org/rest-api/reference/posts/#retrieve-a-post

Wenn Sie eine stärkere benutzerbasierte Authentifizierung benötigen, bietet WordPress eine Möglichkeit, Beiträge stattdessen "privat" zu machen. Diese Einstellung macht Beiträge nur für Benutzerkonten sichtbar, die über die Funktion "read_private_posts" verfügen, die standardmäßig auf die Rollen "Administrator" und "Editor" beschränkt ist. (Hinweis: Privat macht den Inhalt des Beitrags nur privat, seine Titel können weiterhin angezeigt werden.)

Wenn Sie einen benutzerdefinierten Beitragstyp erstellen, wird dieselbe Funktion dem Plural Ihres Typs zugeordnet (mithilfe von plural_base). Für einen Post-Kartentyp steht Ihnen also eine ähnliche Berechtigung "read_private_cards" zur Verfügung, die Sie bei Bedarf Benutzerrollen zuweisen können.

Jetzt ist die Authentifizierung auf Benutzerebene nicht mehr in die REST-API integriert. Die standardmäßige auf WordPress-Cookies basierende Authentifizierung funktioniert einwandfrei, die API bietet jedoch keine Möglichkeit, dieses Cookie abzurufen. Es wird akzeptiert, wenn es vorhanden ist, aber Sie müssen den normalen Anmeldefluss ausführen, um ein solches Cookie zu erhalten. Wenn Sie einen anderen Authentifizierungsansatz wünschen, benötigen Sie ein Plugin dafür.

Es gibt vier solcher Plugins. Dies sind OAuth 1.0, Anwendungskennwörter, JSON-Web-Token und ein Standardauthentifizierungs-Plugin. Beachten Sie, dass die Basisauthentifizierung am einfachsten ist, jedoch auch unsicher und daher nur zu Test- und Entwicklungszwecken empfohlen wird. Es sollte nicht auf einem Live-Produktionsserver verwendet werden.

Weitere Informationen zu diesen Plugins finden Sie hier:

https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/#authentication-plugins

Otto
quelle