REST API в WordPress часто оставляют открытым «по умолчанию», а потом удивляются лишним запросам, шуму в логах и нежелательному сбору данных о сайте. Полностью отключать API обычно плохая идея: редактор блоков, мобильные приложения, некоторые плагины и внешние интеграции используют его легально. На практике чаще нужен не запрет всего подряд, а ограничение доступа для неавторизованных запросов.
Ниже разберём рабочий сценарий: что именно ограничивать, как не сломать сайт, чем отличается код от плагина и как проверить, что всё действительно сработало.
Когда REST API стоит ограничивать
Сначала полезно понять, есть ли у вас реальная проблема. Если в логах много запросов к /wp-json/, а на сайте нет публичных сценариев, где API нужен гостям, ограничение оправдано. Типичные сигналы:
- в access log регулярно идут запросы к
/wp-json/wp/v2/posts,/wp-json/wp/v2/usersи похожим маршрутам; - сканеры и боты получают через API список записей, рубрик и авторов;
- на хостинге растёт число запросов к JSON-эндпоинтам без видимой пользы;
- внешние сервисы работают только после авторизации, а гостевой доступ не нужен.
Если у вас включён блоковый редактор, не стоит рубить API целиком. Gutenberg и часть админки используют REST-запросы для сохранения и загрузки данных. Поэтому задача обычно звучит так: оставить API для авторизованных пользователей и нужных внутренних запросов, а гостям вернуть 401 или 403.
Быстрая диагностика: что именно открыто
Перед изменениями проверьте, как ведёт себя API сейчас. Самый простой тест — открыть базовый маршрут в браузере или через curl.
curl -I https://example.com/wp-json/Если сервер отвечает 200 OK и отдаёт JSON, API доступен. Это ещё не ошибка, но повод проверить, какие маршруты реально нужны без авторизации. Для более точной диагностики полезно посмотреть:
- какие эндпоинты вызываются чаще всего;
- есть ли обращения к
/wp-json/wp/v2/users— этот маршрут часто используют для перечисления авторов; - не завязаны ли на REST сторонние формы, поиск, фронтенд-виджеты или headless-интеграции.
Если сомневаетесь, временно включите логирование на уровне веб-сервера или проверьте журнал безопасности в плагине. Важно не гадать, а увидеть, что именно запрашивают.
Рабочие варианты ограничения REST API
Есть три практических подхода: плагин, код в теме или mu-plugin, и ограничение на уровне сервера. У каждого свой компромисс.
| Способ | Плюсы | Минусы |
|---|---|---|
| Плагин | Быстро, без правок темы, проще откатить | Зависимость от стороннего кода, лишняя нагрузка |
Код в functions.php или mu-plugin | Контроль, предсказуемость, легко точечно исключать маршруты | Нужна аккуратность и тестирование |
| Правила сервера | Срабатывает рано, снижает шум до WordPress | Сложнее поддерживать, легко сломать нужные маршруты |
Для большинства сайтов самый безопасный путь — небольшой код с исключениями. Он позволяет оставить доступ для авторизованных пользователей и при этом закрыть гостевой доступ.
Вариант 1. Ограничить REST API для гостей кодом
Добавьте код в functions.php дочерней темы или, лучше, в отдельный mu-plugin. Этот вариант блокирует неавторизованные запросы, но не мешает входу в админку и работе авторизованных сессий.
<?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 ( strpos( $request_uri, '/wp-json/' ) !== false ) {
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 401 )
);
}
return $result;
} );Этот пример намеренно простой. Если у вас есть публичные маршруты, например для формы обратной связи или мобильного приложения, их нужно исключить отдельно, а не закрывать всё подряд.
Вариант 2. Оставить открытыми только нужные маршруты
Если сайт использует несколько публичных REST-эндпоинтов, лучше не блокировать весь API, а разрешить только конкретные маршруты. Это уже более точная настройка, но и ответственность выше: список нужно поддерживать.
<?php
add_filter( 'rest_authentication_errors', function ( $result ) {
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
$uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
$allowed = array(
'/wp-json/my-plugin/v1/public-form',
'/wp-json/my-plugin/v1/status',
);
foreach ( $allowed as $path ) {
if ( strpos( $uri, $path ) !== false ) {
return $result;
}
}
return new WP_Error( 'rest_forbidden', 'REST API закрыт для гостей.', array( 'status' => 401 ) );
} );Такой подход удобен, если вы точно знаете, какие маршруты должны быть доступны без логина. Если список плавающий, поддержка быстро станет неудобной.
Вариант 3. Скрыть лишние данные из REST-ответов
Иногда API нужен, но не хочется отдавать лишнее. Например, можно убрать из REST-ответов поля, которые не нужны фронтенду или внешним сервисам. Это не замена защите, но полезное дополнение.
<?php
add_filter( 'rest_prepare_user', function ( $response, $user, $request ) {
if ( ! current_user_can( 'list_users' ) ) {
$data = $response->get_data();
unset( $data['email'] );
unset( $data['link'] );
$response->set_data( $data );
}
return $response;
}, 10, 3 );Этот пример не закрывает API, а лишь уменьшает объём данных. Он полезен, если вам важно не показывать лишнее в ответах, но не решает задачу ограничения доступа.
Пошаговая настройка без поломки сайта
- Проверьте, использует ли сайт REST API в админке, редакторе и на фронтенде.
- Сделайте резервную копию файлов и базы.
- Добавьте код в mu-plugin или дочернюю тему, а не в основную тему, если есть риск обновлений.
- Сначала включите ограничение только для гостей.
- Проверьте вход в админку, сохранение записей, работу форм и внешних интеграций.
- Если нужен публичный маршрут, добавьте его в список исключений.
Если вы предпочитаете плагин вместо кода, выбирайте тот, который позволяет точечно управлять REST-доступом, а не просто «выключает всё». Но даже в этом случае проверьте, не конфликтует ли он с редактором блоков и плагинами, которые используют API для AJAX-подобных запросов.
Как проверить, что ограничение работает
После внедрения важно проверить не только код ответа, но и реальные сценарии. Минимальный чек:
- открыть
/wp-json/в режиме инкогнито; - проверить, что гостевой запрос получает
401или403, если это было задумано; - авторизоваться в админке и убедиться, что редактор записей работает;
- сохранить запись, страницу и настройки плагинов, которые завязаны на REST;
- проверить фронтенд-формы и интеграции, если они есть;
- посмотреть логи сервера: лишние запросы к API должны исчезнуть или стать заметно реже.
Для быстрой проверки ответа удобно использовать curl:
curl -I https://example.com/wp-json/wp/v2/postsЕсли вы закрывали API для гостей, неавторизованный запрос должен возвращать не 200. Если всё ещё приходит 200, значит правило не сработало или его перебивает другой плагин/серверная настройка.
Частые ошибки и как их исправить
Полностью отключили REST API
Это самая частая ошибка. После такого ломаются блоковый редактор, часть плагинов и иногда даже элементы админки. Исправление простое: не отключайте API целиком, а ограничьте только неавторизованные запросы или только конкретные маршруты.
Добавили код в активную тему
После обновления темы ограничение исчезает. Для технических правил лучше использовать mu-plugin или дочернюю тему. Так настройка не потеряется при обновлении.
Не учли публичные маршруты
Если у вас есть формы, интеграции или внешние сервисы, они могут обращаться к REST без логина. Перед блокировкой составьте список реально используемых маршрутов. Иначе получите «случайную» поломку, которую сложно связать с изменением.
Смотрят только на код ответа
Иногда запрос действительно блокируется, но сайт продолжает работать нестабильно из-за кеша, старых правил безопасности или конфликтующего плагина. Проверяйте не только ответ API, но и поведение редактора, форм и авторизованных пользователей.
Безопасность и производительность: что ещё имеет смысл сделать
Если цель — уменьшить поверхность атаки и шум, ограничение REST API лучше сочетать с другими мерами:
- убрать лишние публичные данные из профилей авторов и записей;
- проверить, не торчит ли в API чувствительная мета-информация от плагинов;
- не держать на сайте старые плагины, которые регистрируют открытые маршруты без необходимости;
- следить за логами 404 и 401 на
/wp-json/— это помогает увидеть сканирование и перебор; - если используете кеширование, убедиться, что оно не кэширует ответы, зависящие от авторизации.
Если нужна более широкая чистка технических дублей и служебного мусора, иногда удобнее закрывать не только REST, но и другие лишние точки входа через один аккуратный набор правил. В таких задачах полезны плагины уровня Clearfy Pro, если вам нужен именно набор технических настроек, а не один точечный фильтр.
Главная мысль простая: REST API в WordPress не нужно ломать ради безопасности. Его нужно сузить до того уровня, который реально нужен вашему сайту. Тогда вы убираете лишний доступ, но не создаёте себе новые проблемы в админке и интеграциях.