REST API в WordPress часто нужен для редактора блоков, мобильных приложений, интеграций и фронтенд-скриптов. Но на обычном сайте он нередко открыт шире, чем требуется: по адресу /wp-json/ можно увидеть структуру сайта, типы записей, таксономии и часть служебных данных. Если задача — сократить лишнюю поверхность атаки и убрать доступ к REST API для гостей, это лучше делать точечно, а не «рубить» всё подряд.
Ниже — рабочий сценарий: сначала понять, что именно использует REST API на сайте, затем закрыть его только для неавторизованных пользователей и проверить, что редактор, админка и нужные интеграции продолжают работать.
Когда REST API лучше ограничить, а когда не трогать
Полностью отключать REST API на живом сайте — плохая идея, если у вас работает редактор блоков, headless-фронтенд, формы, поиск, мобильные приложения или плагины, которые ходят в /wp-json/. В таких случаях нужно не отключение «всего», а ограничение доступа для гостей.
Ограничение обычно уместно, если сайт:
- обычный корпоративный или контентный, без публичного API;
- не использует внешние сервисы, которые обращаются к REST API без авторизации;
- не имеет фронтенд-логики, завязанной на
wp-json; - нуждается в уменьшении лишних публичных ответов и шумов в логах.
Что именно проверять перед изменением
Сначала откройте в браузере /wp-json/ и несколько типовых эндпоинтов, например /wp-json/wp/v2/posts. Если сайт отдаёт JSON без авторизации, это нормально для WordPress по умолчанию, но именно это и будем ограничивать для гостей.
Параллельно проверьте:
- работает ли редактор блоков в админке;
- нет ли фронтенд-форм, которые отправляют запросы в REST API;
- используются ли плагины поиска, фильтров, комментариев или кэша, которые завязаны на
wp-json; - есть ли кастомные интеграции с внешними системами.
Диагностика: как понять, что REST API сейчас открыт лишним пользователям
Самый простой способ — посмотреть ответ без авторизации. Если вы видите JSON с маршрутами и данными сайта, значит доступ открыт. Это не ошибка само по себе, но для части проектов это избыточно.
Дополнительно проверьте заголовки и ответы через curl:
curl -I https://example.com/wp-json/Если нужен более наглядный тест, попробуйте запрос к записи:
curl https://example.com/wp-json/wp/v2/posts?per_page=1Для гостя ответ обычно приходит без авторизации. Если после внедрения ограничения вы получите 401 или 403, это ожидаемо. Главное — чтобы админка и нужные сервисы не перестали работать.
Пошаговое решение: ограничить REST API только для гостей
Надёжнее всего делать это через небольшой код в дочерней теме или в собственном мини-плагине. Так вы контролируете логику и не зависите от стороннего плагина, который может закрыть больше, чем нужно.
Вариант через фильтр rest_authentication_errors
Этот способ блокирует REST API для неавторизованных пользователей, но оставляет доступ для залогиненных. Для большинства типовых сайтов это самый предсказуемый вариант.
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 403 )
);
} );Что важно: этот код не «ломает» WordPress целиком, а только возвращает ошибку на REST-запросы для гостей. Но если у вас есть публичные интеграции, они тоже перестанут работать без авторизации.
Вариант с исключением для конкретных маршрутов
Иногда нужно оставить открытым, например, endpoint формы, поиска или собственного плагина. Тогда лучше не блокировать всё подряд, а разрешить только нужные маршруты.
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
$allowed_prefixes = array(
'/wp-json/my-plugin/v1/public/',
'/wp-json/wp/v2/search',
);
foreach ( $allowed_prefixes as $prefix ) {
if ( strpos( $request_uri, $prefix ) !== false ) {
return $result;
}
}
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 403 )
);
} );Этот вариант уже требует аккуратности: сравнение по REQUEST_URI грубое, и при сложной маршрутизации лучше проверять конкретные REST-маршруты через собственную логику плагина, а не через строку URL.
Плагин или код: что выбрать на практике
Если задача одноразовая и понятная, код обычно надёжнее. Плагин имеет смысл, когда нужно управлять несколькими настройками безопасности без правки темы. Например, в Clearfy Pro есть инструменты для технической чистки и отключения лишних функций WordPress, если вам удобнее собирать такие настройки в одном месте: https://wpshop.ru/plugins/clearfy.
| Подход | Плюсы | Минусы |
|---|---|---|
| Код в мини-плагине | Точный контроль, нет лишней логики | Нужно следить за обновлениями и совместимостью |
| Плагин безопасности/оптимизации | Удобно для админов, меньше ручной работы | Может закрыть больше, чем нужно |
| Отключение всего REST API | Просто на словах | Часто ломает редактор и интеграции |
Как проверить, что решение сработало
После внедрения не ограничивайтесь открытием главной страницы. Проверка должна быть технической и короткой.
- Откройте
/wp-json/в режиме инкогнито — должен быть отказ в доступе или пустой ответ в зависимости от вашей логики. - Проверьте
/wp-json/wp/v2/postsбез авторизации. - Зайдите в админку и откройте редактор записи — он должен работать как раньше.
- Если на сайте есть формы, поиск или фильтры, отправьте тестовый запрос и посмотрите, не появились ли ошибки в консоли браузера.
- Проверьте логи сервера на 403/401 и убедитесь, что они приходят только от гостей, а не от внутренних сервисов.
Если у вас есть доступ к консоли, можно быстро проверить ответ так:
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-json/Для гостя после ограничения код должен быть не 200. Для авторизованного пользователя поведение зависит от выбранной схемы, но в любом случае редактор и админка должны остаться рабочими.
Частые ошибки и как их исправить
Сломали редактор блоков
Это происходит, когда REST API отключили полностью, а не только для гостей. Проверьте, не используется ли глобальный запрет через rest_endpoints или агрессивный код в functions.php. Для редактора блоков нужен рабочий REST API в админской части.
Перестали работать формы или поиск
Некоторые плагины отправляют данные через REST API даже на публичной части сайта. Если после ограничения что-то перестало отправляться, найдите конкретный маршрут и добавьте его в исключения, а не откатывайте всё решение.
Появились ошибки 403 у авторизованных пользователей
Частая причина — проверка is_user_logged_in() срабатывает не там, где нужно, или код вставлен слишком поздно. Лучше держать такую логику в отдельном плагине и не смешивать её с шаблонами темы.
Сделали фильтрацию по строке URL и промахнулись
Если сравнивать только REQUEST_URI, можно случайно заблокировать лишнее или, наоборот, оставить доступ там, где его быть не должно. Для сложных проектов лучше ограничивать только конкретные маршруты и тестировать их отдельно.
Безопасность и производительность: что ещё имеет смысл проверить
Ограничение REST API — не замена базовой гигиене. Если цель именно уменьшить поверхность атаки, проверьте ещё несколько вещей:
- актуальность ядра, темы и плагинов;
- наличие двухфакторной авторизации для админов;
- ограничение XML-RPC, если он не нужен;
- отсутствие лишних публичных пользователей с правами выше минимальных;
- корректную работу кэша после изменения логики REST API.
Если сайт активно использует технические отключения и чистку, удобнее держать такие настройки в одном месте, а не размазывать по нескольким файлам темы. Но даже в этом случае каждое ограничение нужно проверять отдельно: безопасность не любит «настроил и забыл».
Если после внедрения вы видите, что часть функциональности зависит от REST API, не отключайте его целиком. В WordPress почти всегда лучше сузить доступ до конкретных маршрутов, чем ломать инфраструктуру ради формального «закрытия».