Публичный REST API в WordPress часто нужен для редактора блоков, мобильных приложений и интеграций. Но на обычном сайте он нередко открывает лишние данные, создает шум в логах и дает боты для сканирования. Если задача не в том, чтобы полностью сломать API, а в том, чтобы закрыть его для гостей, это можно сделать аккуратно: оставить доступ авторизованным пользователям и заблокировать публичные запросы.
Ниже разберем рабочий сценарий: как понять, что REST API действительно мешает, чем отличается блокировка через код от плагина, как не сломать админку и как проверить результат после внедрения.
Когда REST API лучше ограничить, а не отключать целиком
Полное отключение REST API почти всегда плохая идея для сайта на свежем редакторе Gutenberg. Админка, предпросмотр, некоторые плагины и внешние сервисы используют /wp-json/. Поэтому безопаснее ограничить только неавторизованные запросы.
Типичные ситуации, когда это оправдано:
- сайт-визитка или корпоративный сайт без внешних интеграций;
- в логах много запросов к
/wp-json/wp/v2/usersи похожим маршрутам; - нужно уменьшить поверхность атаки и убрать лишнюю публичную выдачу;
- плагин безопасности показывает запросы к REST API от ботов.
Диагностика проблемы: что именно открыто
Сначала проверьте, используется ли API реально. Не ориентируйтесь только на ощущение. Откройте в браузере или через curl несколько адресов:
curl -I https://example.com/wp-json/curl -s https://example.com/wp-json/wp/v2/users | headЕсли первый запрос возвращает 200 OK, а второй отдает список пользователей или хотя бы структуру ответа, публичный REST API доступен. Это не ошибка само по себе, но для части сайтов это лишнее.
Еще один признак — запросы в DevTools на фронтенде. Если тема или плагин дергают REST API для обычной страницы, блокировать все подряд нельзя: сначала нужно понять, кто делает запрос и зачем.
Что проверить перед изменениями
- используете ли вы Gutenberg или редактор сайта;
- есть ли мобильное приложение, внешняя CRM, headless-часть или интеграция с фронтендом;
- не завязаны ли на 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;
}
return new WP_Error(
'rest_disabled',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 401 )
);
} );Этот вариант жесткий: он закрывает REST API для всех гостей. Если вам нужно оставить публичные маршруты, например для контактной формы или собственного эндпоинта, лучше сделать исключение по пути.
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
if ( strpos( $request_uri, '/wp-json/myplugin/v1/public-form' ) !== false ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
return new WP_Error( 'rest_disabled', 'REST API закрыт для гостей.', array( 'status' => 401 ) );
} );Если нужен более мягкий режим, можно не блокировать API целиком, а скрыть только список пользователей и похожие чувствительные маршруты. Для этого удобнее использовать rest_endpoints, но здесь важно не переборщить: удаляйте только то, что точно не используется.
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
}
if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
}
return $endpoints;
} );Плагин, код или сервер: что выбрать
| Подход | Плюсы | Минусы | Когда брать |
|---|---|---|---|
Код через rest_authentication_errors | Точный контроль, без лишних зависимостей | Нужно тестировать совместимость | Если есть доступ к теме или мини-плагину |
| Плагин безопасности | Быстро включить, часто есть UI | Может скрывать логику и добавлять лишние правила | Если нужен быстрый старт без разработки |
| Ограничение на уровне Nginx/Apache | Снимает часть нагрузки раньше PHP | Легко задеть нужные маршруты | Если нужно резать трафик до WordPress |
Если вы уже используете Clearfy Pro, имеет смысл сначала проверить, не закрывает ли он часть лишних публичных точек и дублей в связке с другими настройками. Но для точечного ограничения REST API код обычно прозрачнее и предсказуемее.
Проверка результата после внедрения
После сохранения изменений проверьте несколько сценариев:
- Откройте
/wp-json/в режиме инкогнито. Для жесткой блокировки должен быть ответ401или похожая ошибка доступа. - Авторизуйтесь в админке и повторите запрос. Для администратора API должен работать.
- Откройте редактор записи и убедитесь, что он сохраняет контент и загружает данные без ошибок.
- Проверьте фронтенд: формы, поиск, фильтры, комментарии, если они завязаны на API.
Удобно проверить ответ через консоль:
curl -I https://example.com/wp-json/
curl -I https://example.com/wp-json/wp/v2/postsЕсли вы видите 401 Unauthorized для гостя и нормальный ответ после входа в админку, настройка работает как задумано.
Частые ошибки и как их исправить
Сломали редактор блоков
Чаще всего это происходит, когда блокируют REST API полностью без исключений. Gutenberg использует API для загрузки и сохранения данных. Решение простое: не режьте все подряд, а ограничивайте доступ только для гостей или оставляйте нужные маршруты.
Перестали работать формы и фильтры
Некоторые темы и плагины используют REST API для AJAX-запросов. Если после блокировки что-то перестало обновляться, ищите запросы к /wp-json/ в DevTools и добавляйте исключение для конкретного маршрута.
Правило в .htaccess закрыло лишнее
Серверные правила удобны, но опасны тем, что легко задеть служебные запросы. Если вы не уверены, сначала решайте задачу на уровне WordPress, а не Apache или Nginx.
Проверяли только главную страницу
Это типичная ошибка. REST API может использоваться на странице записи, в админке, в поиске или в отдельном шаблоне. Проверять нужно не один URL, а весь сценарий, который реально есть на сайте.
Практические советы по безопасности и производительности
Ограничение REST API не заменяет базовую защиту. Если цель — уменьшить шум и поверхность атаки, добавьте еще несколько точечных мер:
- не публикуйте лишние данные пользователей в профилях и авторах;
- проверьте, не отдает ли тема служебные поля в JSON-ответах;
- ограничьте доступ к
/wp-json/wp/v2/users, если список авторов не нужен; - следите за логами после обновления плагинов: некоторые из них начинают активно использовать API только после апдейта;
- не отключайте REST API наугад на продакшене без теста на копии сайта.
Если вам нужно не только закрыть API, но и убрать лишние публичные точки в целом, имеет смысл смотреть шире: индексация, XML-карта сайта, дубли архивов и служебные страницы часто дают больше пользы при аудите, чем одна точечная блокировка.
В рабочем проекте я бы делал так: сначала проверка реального использования, потом мягкое ограничение для гостей, затем тест редактора и форм, и только после этого — более жесткие серверные правила, если они действительно нужны.