WordPress

rest api — Ustaw obowiązkową autoryzację na trasach niestandardowych

  • 22 maja, 2019
  • 4 min read
rest api — Ustaw obowiązkową autoryzację na trasach niestandardowych


Późno, ale może pomocne dla innych czytelników, ponieważ dodałem rozwiązanie konkretnie do powyższego kodu tego pytania.

Rozwiązanie: Funkcja wywołania zwrotnego uprawnień

WordPressa: wersja 5.7.2
PHP: wersja 7.4
gospodarz: hostmonster.com
klient: Okna 10
przeglądarki: przetestowane na Chrome, Firefox, nawet Edge ? działało

Kod (PHP kod w function.php zainstalowanego motywu):

add_action('rest_api_init', function() {
    /**
     * Register here your custom routes for your CRUD functions
     */
    register_rest_route( 'mysite/v1', '/ads/', array(
        array(
            'methods'  => WP_REST_Server::READABLE, // = 'GET'
            'callback' => 'get_ads',
            // Always allow, as an example
            'permission_callback' => '__return_true'
        ),
        array(
            'methods'  => WP_REST_Server::CREATABLE, // = 'POST'
            'callback' => 'create_ad',
            // Here we register our permissions callback
            // The callback is fired before the main callback to check if the current user can access the endpoint
            'permission_callback' => 'prefix_get_private_data_permissions_check',
        ),
    ));
});

// The missing part:
// Add your Permission Callback function here, that checks for the cookie
// You should define your own 'prefix_' name, though

function prefix_get_private_data_permissions_check() {
    // Restrict endpoint to browsers that have the wp-postpass_ cookie.

    if ( !isset($_COOKIE['wp-postpass_'. COOKIEHASH] )) {
        return new WP_Error( 'rest_forbidden', esc_html__( 'OMG you can not create or edit private data.', 'my-text-domain' ), array( 'status' => 401 ) );
    };
    return true;
};

function create_ad() {
    global $wpdb;

    $result = $wpdb->query(...);

    return $result;
}

function get_ads() {
    global $wpdb;

    $ads = $wpdb->get_results('SELECT * from `ads`');

    return $ads;
}

Upewnij się, że zawierasz na swojej stronie HTML credentials: 'same-origin' w twoim żądaniu HTTP.

Warto przeczytać!  Dodanie niestandardowej kontrolki PanelColorSettings do bloku podstawowego i użycie ślimaka koloru w niestandardowej nazwie klasy

Kod (HTML z inline <script> ... </script>):

<script>

// Here comes the REST API part:
// HTTP requests with fetch() promises

function getYourAds() {
  let url="
  fetch(url, {
    method: 'GET',
    credentials: 'same-origin', // <-- make sure to include credentials
    headers:{
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        //'Authorization': 'Bearer ' + token  <-- not needed, WP does not check for it
    }
  }).then(res => res.json())
  .then(response => get_success(response))
  .catch(error => failure(error));
};

function insertYourAds(data) {
  let url="
  fetch(url, {
    method: 'POST',
    credentials: 'same-origin', // <-- make sure to include credentials
    headers:{
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        //'Authorization': 'Bearer ' + token  <-- not needed, WP does not check for it
    },
    body: JSON.stringify(data)
  }).then(res => res.json())
  .then(response => create_success(response))
  .catch(error => failure(error));
};

// your Success and Failure-functions:

function get_success(json) {
  // do something here with your returned data ....
  console.log(json);
};

function create_success(json) {
  // do something here with your returned data ....
  console.log(json);
};

function failure(error) {
  // do something here ....
  console.log("Error: " + error);
};

</script>

Końcowe przemyślenia:

Jest 'Authorization': 'Bearer ' + token konieczne w nagłówku żądania HTTP?

Po kilku testach zdałem sobie z tego sprawę if ( !isset($_COOKIE['wp-postpass_'. COOKIEHASH] )) { ... w ciągu Oddzwanianie do uprawnień nie tylko sprawdza, czy plik Cookie jest ustawiony w przeglądarce klienta, ale wydaje się również, że sprawdza jego wartość (token JWT).

Warto przeczytać!  jquery — javascript i css nie ładują się poprawnie w witrynie WordPress

Ponieważ sprawdziłem tak jak w przypadku mojego początkowego kodu, przekazując fałszywy token, eliminując plik cookie lub pozostawiając otwartą sesję, ale zmieniając hasło do witryny w zapleczu (stąd WordPress utworzyłby nowy token, stąd wartość set wp_postpass_ plik cookie zmieniłby się) i wszystkie testy przebiegły poprawnie – REST API zablokowane, nie tylko weryfikujące obecność cookie, ale także jego wartość (co jest dobre – dziękuję zespołowi WordPress).

Źródła:
Znalazłem następujący zasób dotyczący powyższych przemyśleń w sekcji FAQ:

Dlaczego interfejs API REST nie weryfikuje przychodzącego nagłówka Origin? Czy to naraża moją witrynę na ataki CSRF?

Ponieważ interfejs API REST WordPress nie weryfikuje nagłówka Origin żądań przychodzących, dostęp do publicznych punktów końcowych interfejsu API REST można uzyskać z dowolnej witryny. Jest to celowa decyzja projektowa.

Jednak WordPress ma istniejący mechanizm ochrony CSRF, który wykorzystuje liczby jednorazowe.

I według moich dotychczasowych testów, sposób uwierzytelniania WP działa doskonale.

Kciuk w górę ? dla zespołu WordPress

Dodatkowe 2 źródła z WordPress Podręcznik API REST:

Podręcznik interfejsu API REST / Rozszerzanie interfejsu API REST / Trasy i punkty końcowe
Podręcznik interfejsu API REST / Rozszerzanie interfejsu API REST / Dodawanie niestandardowych punktów końcowych

Warto przeczytać!  rest api — Jak logowanie i rejestracja w wordpress w reagują na natywną aplikację

Dla zainteresowanych pełną historią moich odkryć, link do mojego wątku z odpowiedziami, fragmentami kodu i dodatkowymi ustaleniami.

Jak wymusić uwierzytelnianie w interfejsie API REST dla strony chronionej hasłem przy użyciu niestandardowej tabeli i pobierania () bez wtyczki


Źródło