REST API в WordPress нужен не только для внешних интеграций. Через него работает редактор блоков, часть плагинов, мобильные приложения и некоторые темы. Поэтому задача обычно не в том, чтобы «выключить всё», а в том, чтобы закрыть лишнее для гостей и не сломать сайт.
Типичный сценарий: в логах много запросов к /wp-json/, в выдаче светятся служебные маршруты, а на сайте нет ни фронтенд-приложения, ни публичной интеграции, которой реально нужен открытый API. В таком случае можно ограничить доступ для неавторизованных пользователей и оставить REST API только для входа в админку и внутренних запросов WordPress.
Когда REST API лучше ограничить, а когда не трогать
Полное отключение REST API — плохая идея для большинства сайтов. Гутенберг, некоторые виджеты, формы, плагины кэша, SEO и интеграции могут обращаться к нему даже без вашего явного участия. Поэтому сначала стоит понять, что именно использует API на вашем проекте.
Сначала проверьте зависимости
Если на сайте есть один из этих сценариев, не делайте грубую блокировку:
- редактор блоков WordPress используется для публикации контента;
- есть мобильное приложение или внешняя админка;
- подключены плагины, которые подгружают данные через REST;
- на фронтенде есть кастомный JS, который читает данные из
/wp-json/.
Если ничего из этого нет, а REST API нужен только для ядра WordPress и авторизованных пользователей, ограничение для гостей обычно безопасно.
Диагностика: кто и зачем обращается к /wp-json/
Перед изменениями посмотрите, есть ли реальные обращения к REST API с фронтенда. Это можно сделать в браузере, логах веб-сервера или через инструменты разработчика. Важно не гадать, а увидеть конкретные запросы.
В DevTools откройте вкладку Network и отфильтруйте по wp-json. Если запросы идут только из админки или при редактировании записи, это нормальная ситуация. Если же они идут на публичной части сайта без понятной причины, нужно искать источник: тему, плагин или кастомный скрипт.
Полезно также проверить, не завязан ли фронтенд на публичные маршруты REST. Например, некоторые темы и конструкторы подгружают данные для блоков, списков записей или комментариев именно так.
Как ограничить REST API для гостей через код
Самый предсказуемый способ — добавить фильтр rest_authentication_errors. Он позволяет вернуть ошибку для неавторизованных пользователей до выполнения маршрута. Это лучше, чем пытаться резать доступ на уровне шаблонов или JS.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
// Разрешаем только базовые служебные запросы WordPress, если они нужны.
// Если хотите закрыть вообще всё для гостей, можно вернуть WP_Error без исключений.
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 401 )
);
}
return $result;
} );Этот вариант жесткий: он блокирует REST API для всех неавторизованных запросов. На практике его стоит применять только если вы уверены, что публичных REST-маршрутов на сайте нет.
Мягкий вариант: закрыть только часть маршрутов
Если нужно оставить доступ к отдельным endpoint-ам, лучше проверять маршрут и блокировать только лишнее. Например, можно закрыть пользовательские и служебные маршруты, но оставить то, что реально используется вашим сайтом.
<?php
add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) {
if ( is_user_logged_in() ) {
return $result;
}
$route = $request->get_route();
// Пример: блокируем только список пользователей и служебные маршруты.
$blocked_routes = array(
'#^/wp/v2/users#',
'#^/wp/v2/comments#',
);
foreach ( $blocked_routes as $pattern ) {
if ( preg_match( $pattern, $route ) ) {
return new WP_Error(
'rest_forbidden',
__( 'Маршрут REST API закрыт для гостей.', 'textdomain' ),
array( 'status' => 403 )
);
}
}
return $result;
}, 10, 3 );Такой подход удобнее, если вы хотите уменьшить поверхность атаки, но не ломать весь сайт. Минус в том, что нужно понимать, какие маршруты реально используются.
Плагин или код: что выбрать
Если задача разовая и вы не хотите поддерживать код, можно использовать плагин для чистки и SEO-оптимизации, например Clearfy Pro. Но для ограничения REST API чаще нужен точечный контроль, а не набор общих переключателей. Код в этом случае прозрачнее: вы видите, что именно блокируется, и можете быстро поправить список маршрутов.
| Подход | Плюсы | Минусы |
|---|---|---|
Код через rest_authentication_errors | Точный контроль, не зависит от интерфейса плагина | Нужно аккуратно проверить зависимости |
Код через rest_pre_dispatch | Можно закрывать только отдельные маршруты | Требует анализа используемых endpoint-ов |
| Плагин | Быстрее для нетехнического пользователя | Меньше прозрачности, возможны лишние ограничения |
Пошаговое решение без поломки сайта
- Проверьте, используется ли REST API на фронтенде и в редакторе.
- Сделайте резервную копию файлов и базы.
- Добавьте код в дочернюю тему или в небольшой mu-plugin, а не в основной файл темы.
- Начните с мягкой блокировки отдельных маршрутов, если есть сомнения.
- Очистите кэш страницы и кэш плагина, если он используется.
- Проверьте публичные страницы, редактор записей и формы на сайте.
Если вы работаете через mu-plugin, это удобнее для таких ограничений: код не пропадет после обновления темы и не зависит от активной темы.
Как проверить, что ограничение сработало
Проверка должна быть не только визуальной. Нужно убедиться, что гостевой доступ действительно закрыт, а авторизованный — работает как раньше.
Проверка в браузере
Откройте в инкогнито адрес /wp-json/ и несколько типовых маршрутов, например /wp-json/wp/v2/posts. Если вы применили жесткую блокировку, должен возвращаться ответ 401 или 403, а не список данных.
Проверка через curl
curl -I https://example.com/wp-json/wp/v2/postsСмотрите на код ответа. Для закрытого маршрута у гостей это должен быть не 200. Если маршрут по-прежнему отдает данные, значит фильтр не сработал или код подключен не там, где нужно.
После входа в админку проверьте редактор записей. Если блоки не подгружаются, не сохраняются черновики или ломаются автосохранение и комментарии, значит вы закрыли слишком много.
Частые ошибки и как их исправить
- Код добавили в functions.php родительской темы. После обновления тема может перезаписаться. Перенесите код в дочернюю тему или mu-plugin.
- Сразу заблокировали весь REST API. Это часто ломает редактор и плагины. Начинайте с отдельных маршрутов.
- Не проверили кэш. Страница может продолжать отдавать старые ответы. Очистите серверный и плагинный кэш.
- Не учли кастомный фронтенд. Если тема или JS читает данные через REST, сайт начнет терять контент. Сначала найдите все обращения к
/wp-json/. - Ожидали, что блокировка REST API скроет сайт от индексации. Это разные задачи. Для индексации нужны robots.txt, noindex и контроль канонических URL.
Безопасность и производительность: что даст ограничение
Закрытие лишних REST-маршрутов не делает сайт «защищенным полностью», но уменьшает количество публичных точек входа и шум в логах. Это полезно, если сайт небольшой, без публичного API и без внешних интеграций.
С точки зрения производительности эффект обычно не драматический. Но если у вас много лишних запросов к REST с фронтенда, после точечной блокировки может стать меньше бесполезных обращений. Главное — не путать это с полноценной оптимизацией кэша и базы данных.
Если нужен более широкий набор технических настроек, иногда удобнее собрать их в одном месте и не держать россыпь мелких сниппетов. В таких случаях имеет смысл смотреть в сторону инструментов вроде Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но даже тогда логику блокировки лучше перепроверять вручную, а не полагаться только на переключатель в интерфейсе.
Что делать, если REST API нужен частично
Иногда правильное решение — не отключать API, а ограничить только конкретные маршруты и оставить остальное. Это актуально для сайтов, где есть авторизация, редактор блоков и отдельные интеграции. В таком случае список блокируемых endpoint-ов лучше вести отдельно и обновлять вместе с кодом темы или плагина.
Если после внедрения ограничения что-то сломалось, откатите фильтр и проверьте, какой именно маршрут нужен проблемному плагину или скрипту. Это быстрее, чем пытаться «лечить» сайт общими запретами.