REST API в WordPress часто нужен для редактора, мобильных приложений, некоторых плагинов и фронтенд-скриптов. Но на публичном сайте его нередко оставляют открытым без необходимости: в ответах видно лишние данные, появляются запросы к /wp-json/, а в логах — обращения ботов к эндпоинтам, которые не дают бизнес-пользы. Если задача именно в том, чтобы закрыть REST API для гостей, а не ломать весь API целиком, это можно сделать аккуратно.
Ниже — рабочий сценарий: сначала определяем, что именно использует API на сайте, затем ограничиваем доступ только для неавторизованных пользователей и проверяем, что админка, блок-редактор и нужные плагины продолжают работать.
Когда это вообще имеет смысл
Полностью отключать REST API на живом сайте — плохая идея. WordPress использует его не только для внешних интеграций, но и для штатных функций админки. Гораздо чаще нужен более узкий вариант: скрыть публичные данные от гостей, но оставить доступ для авторизованных пользователей и внутренних запросов.
Типичные случаи:
- сайт не использует headless-архитектуру и не отдаёт контент через REST наружу;
- в логах много обращений к
/wp-json/wp/v2/posts,/wp-json/oembed/1.0и похожим маршрутам от ботов; - нужно уменьшить поверхность атаки и убрать лишнюю публичную выдачу;
- на сайте есть плагины, которым API нужен только в админке.
Диагностика: что сломается, если закрыть API без проверки
Перед изменениями не стоит гадать. Сначала посмотрите, кто реально обращается к REST API и какие маршруты используются. Это можно сделать в браузере и в логах сервера.
Что проверить вручную
- Откройте главную страницу и админку, затем посмотрите вкладку Network в DevTools.
- Проверьте, есть ли запросы к
/wp-json/на фронтенде. - Посмотрите, не использует ли сайт блоки, формы, поиск или виджеты, которые подгружают данные через REST.
- Если стоит кэш-плагин, проверьте его настройки на предмет интеграции с REST API.
Отдельно посмотрите, не используется ли API в плагинах для редактора, аналитики или внешних сервисов. Если у вас есть staging-копия, тестируйте сначала там.
Пошаговое решение: закрываем REST API для гостей
Самый безопасный вариант — не отключать API целиком, а ограничить доступ для неавторизованных пользователей. Это можно сделать через фильтр rest_authentication_errors. Он срабатывает до выполнения маршрута и позволяет вернуть ошибку для гостей.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
// Разрешаем только базовые служебные запросы, если они нужны.
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
if ( false !== strpos( $request_uri, '/wp-json/' ) ) {
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 401 )
);
}
return $result;
} );Этот вариант лучше, чем грубая блокировка на уровне functions.php без условий, потому что он не вмешивается в авторизованные сценарии. Но если у вас есть публичные эндпоинты, которые действительно нужны, их придётся разрешить отдельно.
Если нужно оставить только отдельные маршруты
Иногда сайт использует, например, oEmbed или конкретный endpoint плагина. Тогда можно разрешить только нужные пути, а всё остальное закрыть. Логика будет такой: если пользователь не авторизован и маршрут не входит в белый список — возвращаем ошибку.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
$path = isset( $_SERVER['REQUEST_URI'] ) ? wp_parse_url( wp_unslash( $_SERVER['REQUEST_URI'] ), PHP_URL_PATH ) : '';
$allowed = array(
'/wp-json/oembed/1.0',
);
foreach ( $allowed as $prefix ) {
if ( 0 === strpos( $path, $prefix ) ) {
return $result;
}
}
return new WP_Error(
'rest_forbidden',
__( 'REST API закрыт для гостей.', 'textdomain' ),
array( 'status' => 401 )
);
} );Если вы не уверены, какие маршруты нужны, не начинайте с белого списка наугад. Сначала соберите фактические запросы из браузера и логов, иначе легко отрезать рабочую интеграцию.
Сравнение подходов: плагин, код или серверная блокировка
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
Код через rest_authentication_errors | Нужен точечный контроль | Гибко, прозрачно, можно оставить белый список | Нужно понимать, какие маршруты используются |
| Плагин для ограничения REST API | Нет доступа к коду или нужен быстрый старт | Меньше ручной работы | Риск лишней логики и конфликтов с другими плагинами |
| Блокировка на уровне сервера | Нужно закрыть доступ до PHP | Снижает нагрузку | Легко сломать легитимные запросы и админские сценарии |
Если нужен не только контроль REST API, но и чистка лишних технических сущностей WordPress, иногда удобнее решать задачу комплексно через набор настроек. Например, в Clearfy Pro есть инструменты для отключения части лишнего технического шума и оптимизации сайта: https://wpshop.ru/plugins/clearfy.
Проверка результата после внедрения
После изменения не ограничивайтесь открытием главной страницы. Проверьте несколько сценариев отдельно.
Что должно работать
- вход в админку;
- редактирование записей и страниц;
- загрузка медиафайлов;
- работа плагинов, если они завязаны на REST API;
- открытие страниц сайта для обычного посетителя.
Что должно быть закрыто
- запросы к
/wp-json/из режима инкогнито; - публичные REST-маршруты, которые вы не разрешали;
- неавторизованный доступ к данным, которые раньше отдавались без проверки.
Проверить можно прямо в браузере:
curl -I https://example.com/wp-json/Если всё настроено как задумано, неавторизованный запрос должен вернуть отказ, а не полноценный JSON-ответ с данными сайта. Для авторизованной сессии поведение будет другим, и это нормально.
Частые ошибки и как их исправить
Сломали редактор или блоки Gutenberg
Причина обычно в слишком грубой блокировке всего REST API. Проверьте, не режете ли вы запросы для авторизованных пользователей. Если да — уберите этот запрет и ограничьте только гостей.
Перестали работать формы, поиск или виджеты
Некоторые темы и плагины используют REST API для подгрузки данных на фронтенде. Посмотрите Network в браузере и найдите конкретный маршрут. После этого добавьте его в белый список, а не открывайте весь API обратно.
Появились ошибки у плагина кэша или аналитики
Часть плагинов делает служебные запросы через REST. Если после ограничения API что-то сломалось, проверьте документацию плагина и его сетевые запросы. Иногда достаточно разрешить один маршрут, а не возвращать всё как было.
Блокировка сделана через .htaccess без теста
Это частая ошибка: правила на уровне веб-сервера выглядят просто, но легко зацепить нужные маршруты. Если нет уверенности, начинайте с PHP-фильтра и только потом переносите ограничение на серверный уровень.
Практические советы по безопасности и производительности
Ограничение REST API — не замена нормальной защите сайта. Оно уменьшает количество лишних публичных ответов, но не закрывает уязвимости в темах, плагинах и правах пользователей.
- не храните код в случайных сниппетах без контроля версий;
- добавляйте изменения в дочернюю тему или в отдельный мини-плагин;
- проверяйте, не использует ли сайт headless-функции, интеграции с внешними системами или мобильное приложение;
- после правок очищайте кэш страницы и объектный кэш, если он есть;
- не блокируйте API на проде без теста на staging.
Если у вас задача шире, чем просто REST API, и нужно навести порядок в технических настройках WordPress, имеет смысл смотреть на комплексные инструменты, а не собирать всё вручную. Но в любом случае сначала фиксируйте, какие именно маршруты используются на сайте, и только потом ограничивайте доступ.