REST API в WordPress часто оставляют открытым по умолчанию, а потом удивляются лишним запросам, светящимся endpoint’ам и данным, которые не должны быть доступны анонимному посетителю. Но отключать его целиком — плохая идея: редактор блоков, некоторые плагины и интеграции используют REST API постоянно.
Рабочий сценарий здесь другой: ограничить REST API для гостей, но оставить его для авторизованных пользователей и для тех маршрутов, которые реально нужны сайту. Это полезно, если вы хотите уменьшить поверхность атаки, убрать лишнюю индексацию технических ответов и закрыть публичный доступ к данным, которые не предназначены для анонимного просмотра.
Когда это действительно нужно
Ограничение REST API имеет смысл не на каждом сайте. Если у вас обычный блог без внешних интеграций, анонимный доступ к API чаще всего не нужен. Если же сайт использует блоковый редактор, мобильное приложение, headless-фронтенд, формы, поиск или сторонние сервисы, сначала нужно понять, какие именно запросы идут через REST.
Типичные признаки проблемы
- в логах много запросов к
/wp-json/от ботов и сканеров; - в выдаче и в инструментах проверки видны публичные JSON-ответы с данными сайта;
- плагин безопасности ругается на открытый REST endpoint;
- нужно закрыть доступ к API для гостей, но не ломать админку и редактор.
Если задача звучит как «полностью выключить REST API», сначала остановитесь. Для WordPress это почти всегда избыточно. Безопаснее ограничивать доступ точечно.
Диагностика: что именно использует REST API
Перед изменениями проверьте, какие запросы идут к API на фронтенде и в админке. Самый простой способ — открыть DevTools в браузере и отфильтровать запросы по wp-json. Если сайт большой, дополнительно посмотрите логи веб-сервера или мониторинг запросов в плагине кэша.
Обратите внимание на три вещи:
- есть ли запросы к
/wp-json/wp/v2/на публичной части сайта; - использует ли редактор блоков REST при сохранении и загрузке контента;
- есть ли плагины, которые получают данные через собственные endpoint’ы.
Если вы видите запросы только от гостей и они не нужны для публичной части сайта, ограничение можно внедрять. Если же часть фронтенда зависит от API, лучше закрывать только отдельные маршруты, а не весь REST.
Как ограничить REST API для незалогиненных пользователей
Самый предсказуемый способ — добавить фильтр rest_authentication_errors. Он срабатывает до выполнения маршрута и позволяет вернуть ошибку для гостей. При этом авторизованные пользователи продолжат работать как обычно.
Ниже пример, который блокирует REST API для незалогиненных пользователей, но оставляет доступ к административным и внутренним запросам WordPress, если они выполняются в контексте авторизованной сессии.
<?php
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' => 401 )
);
} );Этот вариант простой, но слишком жёсткий для сайтов, где гостям нужен хотя бы один публичный endpoint. В таком случае лучше разрешить только конкретные маршруты.
Более безопасный вариант: разрешить только нужные маршруты
Если у вас, например, работает публичный поиск или форма, завязанная на REST, можно пропускать только определённые namespace’ы. Ниже пример, где гостям разрешён только wp/v2 для чтения записей и страниц, а всё остальное закрыто. Логику под свой сайт нужно адаптировать.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) || is_user_logged_in() ) {
return $result;
}
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
if ( strpos( $request_uri, '/wp-json/wp/v2/posts' ) !== false || strpos( $request_uri, '/wp-json/wp/v2/pages' ) !== false ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
__( 'REST API закрыт для гостей.', 'textdomain' ),
array( 'status' => 401 )
);
} );Такой подход не идеален, потому что проверка URI грубая. Но для небольших сайтов он понятен и легко отлаживается. Если нужен более точный контроль, лучше использовать rest_pre_dispatch или проверять сам маршрут через объект запроса.
Сравнение подходов
| Подход | Что даёт | Минус |
|---|---|---|
| Плагин безопасности | Быстрое включение без кода | Может закрыть лишнее или конфликтовать с плагинами |
Фильтр rest_authentication_errors | Точный контроль для гостей | Нужно тестировать совместимость |
| Полное отключение REST | Максимальное ограничение | Часто ломает редактор, интеграции и фронтенд |
Если нужен именно контроль доступа, а не «вырубить всё», код обычно надёжнее. Плагин удобен, когда вы не хотите поддерживать собственный сниппет, но тогда обязательно проверьте, не режет ли он нужные запросы.
Пошаговое внедрение без поломки сайта
- Сделайте резервную копию файлов и базы.
- Проверьте, какие страницы и плагины используют REST API.
- Добавьте сниппет в
functions.phpдочерней темы или в mu-plugin. - Очистите кэш страницы и серверный кэш, если он есть.
- Проверьте вход в админку, редактор записей и публичную часть сайта.
Для production-сайта лучше использовать mu-plugin, а не functions.php. Так код не потеряется при смене темы и не будет зависеть от шаблона.
Как проверить, что ограничение сработало
Проверка должна быть не только визуальной. Откройте в браузере адрес /wp-json/ в режиме инкогнито. Если вы закрыли API для гостей, должен возвращаться ответ с ошибкой доступа, а не список маршрутов.
Дальше проверьте авторизованную сессию:
- войдите в админку;
- откройте редактор записи;
- сохраните черновик;
- убедитесь, что блоки и автосохранение работают;
- проверьте плагины, которые получают данные через REST.
Если у вас есть мониторинг запросов, сравните количество обращений к /wp-json/ до и после изменения. Если запросы от гостей исчезли, а админка не сломалась, задача выполнена правильно.
Частые ошибки и как их исправить
Сайт перестал сохранять записи в редакторе
Обычно это значит, что вы закрыли REST API слишком агрессивно. Проверьте, не блокируется ли доступ для авторизованных пользователей и не вмешивается ли сторонний плагин безопасности.
Публичный фронтенд начал отдавать ошибки
Некоторые темы и плагины подгружают данные через REST на клиенте. Если после ограничения сломались блоки, фильтры или поиск, нужно разрешить только нужные маршруты, а не весь API.
Ошибка появляется только на части страниц
Так бывает, когда один шаблон или один блок использует отдельный endpoint. Сравните сетевые запросы на рабочей и проблемной странице, чтобы найти конкретный маршрут.
Кэш мешает увидеть результат
После изменения правил обязательно очистите page cache, object cache и CDN, если он используется. Иначе вы можете смотреть на старый ответ и думать, что правило не сработало.
Что ещё стоит учесть по безопасности и производительности
Ограничение REST API не заменяет нормальную защиту входа, актуальные обновления и контроль прав пользователей. Но в связке с ними оно уменьшает лишний шум и сокращает поверхность атаки.
Если цель — именно техническая чистка сайта, иногда удобнее сначала убрать лишние функции через один инструмент, а не собирать всё вручную. Например, Clearfy Pro от WPShop закрывает часть типовых задач по оптимизации и отключению ненужных элементов, но даже в этом случае логику доступа к REST лучше проверять отдельно: автоматические настройки не должны ломать рабочие интеграции. Ссылка: https://wpshop.ru/plugins/clearfy.
Если у вас сайт с высокой нагрузкой, после ограничения REST API стоит ещё раз посмотреть на логи и метрики. Иногда проблема не в самом API, а в том, что его массово дергают боты, и тогда полезно дополнительно настроить кэширование, rate limiting на уровне сервера или WAF.
Практический ориентир простой: если после внедрения гости больше не получают лишний доступ к API, а редактор и нужные интеграции работают без ошибок, ограничение сделано корректно. Если же пришлось «чинить» сайт после отключения, значит, правило было слишком грубым и его нужно сузить до конкретных маршрутов.