Открытый REST API в WordPress сам по себе не проблема. Проблема начинается, когда сайт отдает слишком много данных неавторизованным запросам: списки записей, пользователей, таксономий, служебные маршруты плагинов. На небольших сайтах это часто просто лишний шум, а на проектах с кастомными типами записей и интеграциями — еще и источник лишней нагрузки и утечек структуры сайта.
Ниже разберем не «выключить все», а нормальный рабочий сценарий: оставить то, что нужно редактору и фронтенду, и ограничить лишнее для гостей.
Когда REST API действительно стоит ограничивать
Сначала проверьте, что именно у вас открыто. Не каждый endpoint нужно закрывать. Например, Gutenberg и часть админки используют REST API постоянно. Если просто заблокировать /wp-json/ целиком, сломаются редактор, автосохранение, некоторые формы, поиск и плагины, которые получают данные через API.
Типичные признаки проблемы
- в
/wp-json/видны маршруты, которые не нужны гостям; - в логах много запросов к REST API от ботов;
- плагины безопасности показывают лишние публичные endpoint’ы;
- на сайте есть кастомные маршруты, которые отдают служебные данные без проверки прав;
- нужно убрать доступ к части API, но оставить редактор и авторизованные запросы.
Что не стоит делать
Не закрывайте REST API через грубую блокировку на уровне сервера без понимания зависимостей. Если у вас есть фронтенд-виджеты, блоки, формы или интеграции с внешними сервисами, они могут перестать получать данные. Сначала определите, какие маршруты реально используются.
Диагностика: какие endpoint’ы доступны гостям
Проверка начинается с обычного запроса к корневому индексу REST API. Откройте /wp-json/ в браузере или выполните запрос из консоли. Если сайт отдает большой список маршрутов, это нормально. Важно понять, какие из них должны быть публичными, а какие — нет.
curl -I https://example.com/wp-json/Если нужен более предметный осмотр, посмотрите конкретные маршруты. Например, часто публично доступны:
/wp-json/wp/v2/posts;/wp-json/wp/v2/pages;/wp-json/wp/v2/categories;/wp-json/wp/v2/tags.
Это не ошибка, если сайт действительно должен отдавать контент наружу. Но если у вас закрытый проект, внутренний портал или сайт, где контент не должен индексироваться и массово читаться через API, такие маршруты лучше ограничить.
Рабочая схема: ограничить REST API только для гостей
Самый безопасный подход — не отключать REST API полностью, а фильтровать ответы для неавторизованных пользователей. Для этого подходит хук rest_authentication_errors. Он срабатывает до выполнения запроса и позволяет вернуть ошибку для гостей.
Ниже пример, который блокирует доступ гостям ко всем REST-запросам, кроме нескольких разрешенных маршрутов. Такой вариант полезен, если вам нужно оставить публичный доступ только к отдельным endpoint’ам.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
$uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
$allowed = array(
'/wp-json/',
'/wp-json/oembed/1.0/embed',
);
foreach ( $allowed as $path ) {
if ( str_contains( $uri, $path ) ) {
return $result;
}
}
return new WP_Error(
'rest_forbidden',
'REST API доступен только авторизованным пользователям.',
array( 'status' => 401 )
);
} );Но у этого варианта есть важная оговорка: он слишком жесткий для большинства обычных сайтов. Если у вас есть публичный контент, блоки, встроенные формы или внешние сервисы, лучше ограничивать не весь API, а отдельные маршруты.
Точечная блокировка отдельных маршрутов
Если задача — убрать только чувствительные данные, удобнее использовать фильтр rest_endpoints. Он позволяет удалить конкретные маршруты из списка доступных endpoint’ов для гостей.
<?php
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( is_user_logged_in() ) {
return $endpoints;
}
$blocked = array(
'/wp/v2/users',
'/wp/v2/comments',
);
foreach ( $blocked as $route ) {
if ( isset( $endpoints[ $route ] ) ) {
unset( $endpoints[ $route ] );
}
}
return $endpoints;
} );Этот способ лучше, если вам нужно скрыть пользователей, комментарии или служебные маршруты, но оставить публичные записи и страницы. Для большинства редакционных сайтов это более практично, чем тотальная блокировка.
Если нужен доступ только к своим кастомным маршрутам
Для собственных endpoint’ов правильнее проверять права внутри callback-функции через current_user_can(). Не полагайтесь только на то, что маршрут «не светится» в интерфейсе. Если endpoint возвращает служебные данные, ограничьте его явно.
<?php
register_rest_route( 'myplugin/v1', '/stats', array(
'methods' => 'GET',
'callback' => function() {
if ( ! current_user_can( 'manage_options' ) ) {
return new WP_Error( 'forbidden', 'Недостаточно прав.', array( 'status' => 403 ) );
}
return array(
'status' => 'ok',
);
},
'permission_callback' => '__return_true',
) );Здесь важен не только permission_callback, но и реальная проверка внутри callback. Это снижает риск случайно открыть данные при доработках.
Сравнение подходов
| Подход | Что делает | Минус | Когда использовать |
|---|---|---|---|
| Полная блокировка REST API | Закрывает все запросы для гостей | Легко ломает редактор и фронтенд | Только для закрытых внутренних сайтов |
rest_authentication_errors | Блокирует запросы до выполнения | Нужно аккуратно составлять исключения | Когда надо ограничить доступ для гостей |
rest_endpoints | Убирает отдельные маршруты | Не защищает уже известные кастомные URL без проверки прав | Когда нужно скрыть только часть API |
Пошаговое внедрение без сюрпризов
- Сделайте резервную копию файла
functions.phpили вынесите код в мини-плагин. - Проверьте, какие маршруты реально используются на сайте и в админке.
- Сначала ограничьте только самые чувствительные endpoint’ы.
- Протестируйте вход в редактор, автосохранение, формы и AJAX-запросы.
- Посмотрите ответы
401и403в браузере и в логах. - Если все работает, расширяйте список ограничений постепенно.
Как проверить, что решение сработало
Проверка должна быть не «страница открылась», а конкретной. Смотрите на ответы API с разных ролей.
- выйдите из админки и откройте
/wp-json/wp/v2/users; - убедитесь, что гостю маршрут недоступен;
- зайдите под администратором и проверьте, что нужные внутренние запросы работают;
- откройте редактор записи и убедитесь, что автосохранение не ломается;
- посмотрите консоль браузера на ошибки запросов к REST API;
- проверьте, не сломались ли формы, которые получают данные через API.
Если у вас есть доступ к серверным логам, полезно проверить, не выросло ли число ошибок 401 и 403 на легитимных запросах. Это быстрый способ понять, не перекрыли ли вы лишнее.
Частые ошибки и как их исправить
Блокируют весь /wp-json/
Так делают чаще всего, когда хотят «закрыть API». В результате ломается редактор и часть плагинов. Исправление простое: верните доступ к нужным маршрутам и ограничьте только чувствительные endpoint’ы.
Проверяют только URL, но не права пользователя
Если кастомный маршрут отдает данные, а внутри callback нет проверки current_user_can(), маршрут остается уязвимым. Исправление: добавьте явную проверку прав и возвращайте WP_Error с кодом 403.
Не тестируют фронтенд после изменений
REST API используют не только в админке. Часто запросы идут из блоков, виджетов, поиска и форм. После изменения обязательно проверьте страницу записи, главную, архивы и формы обратной связи.
Ставят блокировку в тему, а потом теряют ее при обновлении
Если код лежит в functions.php, он исчезнет при смене темы. Для таких задач лучше мини-плагин или mu-plugin. Это надежнее и проще сопровождать.
Что учесть по безопасности и производительности
Ограничение REST API не заменяет нормальную защиту сайта. Если на проекте есть чувствительные данные, дополнительно проверьте права на кастомные маршруты, отключите лишние публичные endpoint’ы плагинов и не публикуйте служебные данные в ответах API.
С точки зрения производительности точечная блокировка полезнее, чем грубое отключение. Вы не ломаете рабочие сценарии и не создаете лишние обходные костыли на фронтенде. Если у вас много технических дублей, лишних маршрутов и служебных страниц, имеет смысл отдельно пройтись по настройкам SEO и чистке сайта — например, через Clearfy Pro, если нужен набор практических инструментов для удаления дублей и технической оптимизации.
Главное правило простое: сначала выясните, какие endpoint’ы реально нужны, потом ограничивайте только лишнее. В WordPress это почти всегда безопаснее, чем пытаться выключить все одним движением.