REST API в WordPress часто оставляют открытым «как есть», а потом удивляются лишним запросам, утечке служебных данных или конфликтам с плагинами безопасности. Полностью отключать API обычно плохая идея: редактор блоков, некоторые темы, формы и интеграции опираются на него напрямую. Рабочий подход другой — сначала понять, что именно используется, а затем ограничить только лишнее.
Ниже разберём сценарий, когда сайт не должен отдавать публично лишние REST-данные, но при этом должен продолжать работать в админке и на фронтенде.
Когда REST API действительно стоит ограничить
Обычно проблема проявляется не в одной ошибке, а в наборе признаков:
- в логах много запросов к
/wp-json/от ботов; - в ответах API видны маршруты, которые не нужны посетителям;
- плагин безопасности ругается на доступ к REST-эндпоинтам;
- на сайте есть публичные формы, но они не используют REST, а только создают шум;
- нужно закрыть доступ к данным пользователей, комментариев или служебных маршрутов.
Если у вас работает редактор блоков, AJAX-запросы темы или интеграция с внешним сервисом, отключать REST целиком не стоит. Лучше ограничить доступ точечно.
Диагностика: что именно открыто и кто этим пользуется
Перед изменениями проверьте, какие маршруты реально доступны. Самый простой способ — открыть базовый индекс REST API в браузере:
https://example.com/wp-json/Если сайт отдаёт большой JSON со списком маршрутов, это нормально. Вопрос в том, какие из них вам нужны. Для проверки конкретного маршрута можно использовать curl:
curl -I https://example.com/wp-json/wp/v2/postsЕсли ответ 200 OK, маршрут доступен. Если вы уже ставили плагины безопасности, проверьте, не блокируют ли они REST-запросы редактора или формы. Частая ошибка — закрыть API на уровне плагина, а потом получить неработающий Gutenberg или отправку комментариев.
Что проверить до внедрения
- открывается ли редактор записей в админке;
- работают ли формы, если они завязаны на REST;
- нет ли ошибок в консоли браузера на страницах с блоками;
- не использует ли тема запросы к
/wp-json/для подгрузки контента; - не завязан ли на REST плагин поиска, фильтрации или кэша.
Пошаговое решение: ограничиваем REST API точечно
Если задача — скрыть REST API для неавторизованных пользователей, но оставить его для админки и внутренних запросов, удобнее всего сделать это через фильтр rest_authentication_errors. Добавьте код в functions.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'] ) : '';
// Пример: не блокируем запросы к wp-json/wp/v2/posts, если они нужны фронтенду.
if ( strpos( $request_uri, '/wp-json/wp/v2/posts' ) !== false ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
__( 'REST API restricted.', 'textdomain' ),
array( 'status' => 403 )
);
} );Этот вариант грубый, поэтому его стоит использовать только после проверки конкретных маршрутов. На практике лучше не резать всё подряд, а отключать только ненужные эндпоинты через register_rest_route в собственном коде или через фильтрацию ответов.
Если нужно убрать из индекса REST API отдельные маршруты, можно скрыть их из ответа корневого индекса. Для этого подходит фильтр rest_endpoints:
add_filter( 'rest_endpoints', function( $endpoints ) {
// Пример: убираем маршрут пользователей из публичного списка.
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
}
return $endpoints;
} );Это не делает маршрут полностью недоступным, но убирает его из стандартного списка. Если нужна именно блокировка, комбинируйте этот фильтр с проверкой прав доступа в rest_authentication_errors.
Сравнение подходов: плагин, код или сервер
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Плагин безопасности | Нужно быстро закрыть типовые риски | Меньше кода, проще откат | Может конфликтовать с редактором и интеграциями |
| Код в теме или мини-плагине | Нужен точечный контроль | Можно ограничить только нужные маршруты | Нужно тестировать вручную |
| Правила на сервере | Нужно резать доступ до WordPress | Снимает нагрузку раньше PHP | Легко сломать легитимные запросы |
Если у вас обычный сайт-визитка, часто достаточно кода. Если сайт активно использует блоки, REST и внешние сервисы, лучше не трогать серверные правила без необходимости.
Как проверить, что ограничение сработало
После внедрения проверьте несколько сценариев:
- откройте
/wp-json/в браузере без авторизации; - проверьте конкретный маршрут через
curl; - войдите в админку и убедитесь, что редактор записей работает;
- откройте страницу с блоками и проверьте консоль браузера;
- посмотрите логи сервера на предмет
403и ошибок JavaScript.
Если после ограничения сломалась загрузка блоков или не отправляются формы, значит вы перекрыли маршрут, который реально использовался. В таком случае проще вернуть код и сузить правило до конкретного эндпоинта.
Частые ошибки и как их исправить
Полное отключение REST API
Это самая частая ошибка. На сайте может перестать работать редактор блоков, некоторые виджеты, формы и интеграции. Если нужен только контроль доступа, блокируйте не весь API, а отдельные маршруты.
Фильтрация по слишком общему условию
Например, проверка только REQUEST_URI без учёта контекста. Такой код легко ломает легитимные запросы. Лучше сначала собрать список нужных маршрутов, а потом закрывать лишние.
Внесение кода в родительскую тему
При обновлении темы ограничение исчезнет. Для постоянного решения используйте дочернюю тему или небольшой mu-plugin.
Игнорирование кэша
После изменений старые ответы могут продолжать отдаваться из кэша. Очистите серверный кэш, кэш плагина и, если нужно, CDN.
Практические советы по безопасности и производительности
Если цель — снизить шум и поверхность атаки, не ограничивайтесь только REST API. Проверьте ещё несколько вещей:
- уберите ненужные публичные маршруты и тестовые endpoints;
- ограничьте доступ к
/wp-json/wp/v2/users, если список пользователей не должен быть публичным; - следите за тем, чтобы плагины не регистрировали лишние REST-маршруты без необходимости;
- не используйте агрессивные правила, если сайт зависит от блоков и AJAX;
- после каждого обновления плагинов перепроверяйте, не появился ли новый маршрут.
Если нужен более широкий набор инструментов для чистки дублей, SEO-настроек и отключения лишних сущностей в WordPress, иногда удобнее вынести это в отдельный набор настроек, а не держать разрозненные сниппеты в теме. Но даже в этом случае важно понимать, что именно отключается и как это влияет на фронтенд.
Главная идея простая: REST API не надо ломать целиком. Его нужно инвентаризировать, закрыть лишнее и оставить то, что реально использует сайт.