REST API в WordPress часто отключают слишком грубо: ставят код из случайной статьи, а потом ловят сломанный редактор, проблемы с мобильными приложениями или конфликт с плагином, который тихо использует JSON-эндпоинты. На практике почти всегда нужен не полный запрет, а контроль доступа к публичным маршрутам.
Если задача звучит как «убрать лишнюю поверхность атаки и сократить публичные запросы», сначала стоит понять, кто именно ходит в /wp-json/, а уже потом выбирать способ: ограничение для гостей, точечная блокировка отдельных маршрутов или полный запрет только на фронтенде.
Когда REST API действительно мешает
Проблема обычно проявляется не в админке, а на публичной части сайта. В логах и инструментах разработчика видно запросы к /wp-json/wp/v2/, а на сайте при этом нет функций, которым REST нужен явно. Но это не значит, что API можно просто выключить: Gutenberg, некоторые формы, кеширующие плагины, интеграции и внешние сервисы могут использовать его косвенно.
Что проверить до изменений
- используется ли блоковый редактор и работает ли он без ошибок;
- есть ли мобильное приложение WordPress или внешняя публикация через API;
- какие плагины обращаются к
/wp-json/в браузере и в сетевых логах; - не завязаны ли на REST формы, поиск, фильтры, AMP или headless-функции;
- есть ли в логах 401/403/404 на JSON-маршруты после установки защитного плагина.
Диагностика: кто использует REST API
Самый быстрый способ — открыть DevTools в браузере и посмотреть сетевые запросы на странице с редактором и на публичной части сайта. Если запросов много, это еще не проблема: важно понять, какие из них критичны. Отдельно проверьте страницу входа, редактирование записи и формы обратной связи.
Если нужен более технический контроль, можно временно включить логирование на уровне сервера или посмотреть обращения в access log. Для WordPress полезно также проверить, не возвращает ли /wp-json/ ошибку после установки ограничений. Если API уже частично сломан, это часто видно по неработающему автосохранению, медиа-вставкам или ошибкам в консоли.
Рабочие варианты: что отключать и что оставить
Полностью отключать REST API имеет смысл редко. Чаще нужен один из трех сценариев: оставить API только для авторизованных пользователей, закрыть отдельные публичные маршруты или убрать только индексацию и лишнюю доступность для гостей.
| Способ | Что делает | Компромисс |
|---|---|---|
| Плагин безопасности | Скрывает или ограничивает REST без ручного кода | Меньше контроля, возможны лишние ограничения |
| Код в теме или mu-plugin | Точечно ограничивает доступ к нужным маршрутам | Нужно тестировать совместимость |
| Только серверное правило | Блокирует часть запросов на уровне nginx/Apache | Можно случайно задеть легитимные интеграции |
Пошаговое решение через код
Если нужен предсказуемый вариант без лишних зависимостей, используйте фильтр rest_authentication_errors. Он позволяет запретить REST API для неавторизованных пользователей, но оставить его для админки и внутренних сценариев, где пользователь уже вошел в систему.
<?php
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'] ) : '';
if ( strpos( $request_uri, '/wp-json/' ) !== false ) {
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 401 )
);
}
return $result;
} );Этот вариант лучше размещать в mu-plugins или в отдельном мини-плагине, а не в functions.php активной темы. Так правило не исчезнет после смены темы и его проще отключить при отладке.
Если нужно не закрывать весь API, а убрать только публичную выдачу записей и страниц, можно работать точечно через проверку маршрута. Это безопаснее, чем рубить все подряд.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) || is_user_logged_in() ) {
return $result;
}
$route = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
$blocked_routes = array(
'/wp-json/wp/v2/posts',
'/wp-json/wp/v2/pages',
'/wp-json/wp/v2/media',
);
foreach ( $blocked_routes as $blocked_route ) {
if ( strpos( $route, $blocked_route ) !== false ) {
return new WP_Error( 'rest_forbidden', 'Маршрут REST API закрыт для гостей.', array( 'status' => 403 ) );
}
}
return $result;
} );Если нужен вариант без кода
Когда сайт ведется без доработок и важна быстрая проверка гипотезы, проще использовать плагин, который умеет ограничивать REST API и не ломает остальной стек. Важно не ставить сразу несколько защитных плагинов с одинаковой функцией: они часто конфликтуют и дублируют правила.
Если у вас уже стоит плагин для технической чистки сайта, например Clearfy Pro, проверьте, не включена ли там похожая опция ограничения REST API или скрытия лишних эндпоинтов. Но даже в этом случае после включения надо тестировать редактор, формы и авторизацию, а не считать настройку «безопасной по умолчанию».
Проверка результата после внедрения
После изменения не ограничивайтесь открытием главной страницы. Нужна короткая, но конкретная проверка, иначе можно пропустить скрытую поломку.
- Откройте
/wp-json/в браузере в режиме инкогнито: должен быть ожидаемый ответ, а не случайная ошибка сервера. - Зайдите в админку и проверьте создание/редактирование записи в Gutenberg.
- Проверьте медиа-библиотеку и вставку изображения в запись.
- Откройте форму комментариев или контактную форму, если она использует REST.
- Посмотрите консоль браузера на наличие ошибок
401,403и сообщений о неудачном автосохранении.
Если сайт использует кеш, очистите его после изменений. Иначе вы можете проверять уже не текущую конфигурацию, а старый ответ из кеша.
Частые ошибки и как их исправить
Полное отключение без проверки зависимостей
Самая частая ошибка — вставить код, который блокирует весь REST API для всех, включая авторизованных пользователей. В результате ломается редактор, а причина выглядит неочевидно. Исправление простое: сначала ограничивайте только гостей и только потом сужайте список маршрутов.
Правило в functions.php вместо отдельного мини-плагина
Если код лежит в теме, его легко потерять при обновлении или смене шаблона. Для технических ограничений лучше использовать mu-plugin или отдельный плагин. Это не только надежнее, но и удобнее для отката.
Блокировка по URL без учета реальных маршрутов
Иногда пытаются фильтровать REST по строке /wp-json/ на уровне веб-сервера и случайно задевают легитимные запросы плагинов. Если нужен серверный уровень, сначала соберите список реально используемых маршрутов и протестируйте их на staging.
Игнорирование кеша и CDN
После включения ограничений старые ответы могут продолжать отдаваться из кеша. Если проверка показывает, что API «вроде бы» еще доступен, очистите серверный кеш, CDN и кеш браузера, а затем повторите тест в инкогнито.
Практические советы по безопасности и производительности
REST API сам по себе не проблема. Проблема начинается, когда публичные маршруты отдают слишком много данных или используются там, где можно обойтись более узким доступом. Если цель — безопасность, лучше закрывать лишнее точечно, чем ломать весь механизм.
Для производительности полезно проверить, не дергает ли фронтенд REST API на каждой загрузке страницы без необходимости. Иногда это делает тема или плагин виджетов, и тогда ограничение API только выявляет скрытую архитектурную проблему. В таких случаях правильнее оптимизировать сам источник запросов, а не маскировать симптом.
Если нужен быстрый аудит дублирующих и лишних технических сущностей на сайте, имеет смысл смотреть на это в комплексе: REST, XML-RPC, sitemap, архивы и служебные страницы. Но каждую настройку лучше проверять отдельно, чтобы понимать, что именно сломалось и почему.