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.
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).
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
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