REST API в WordPress часто оставляют открытым «как есть», а потом получают лишние публичные запросы, утечки служебных данных и шум в логах. Но полностью рубить /wp-json/ нельзя: редактор блоков, часть плагинов и внешние интеграции используют этот же механизм. Рабочая задача здесь не «выключить всё», а аккуратно закрыть API для незалогиненных пользователей и оставить сайт живым.
Когда это действительно нужно
Сценарий обычно один из трёх: в логах много запросов к /wp-json/, сторонний сервис тянет лишние данные, либо вы хотите убрать публичную поверхность атаки без установки тяжёлого security-плагина. Если сайт на классическом контенте и внешних интеграций немного, ограничение REST API для гостей часто даёт понятный выигрыш по шуму и контролю.
Но если у вас фронтенд-редактор, headless-часть, мобильное приложение или плагин, который получает данные через REST без авторизации, сначала нужно проверить, какие именно маршруты используются. Иначе можно сломать не только публичные запросы, но и админку.
Диагностика: что именно использует REST API
Перед изменениями откройте сайт в браузере и посмотрите, какие запросы идут к /wp-json/ в DevTools. На обычной теме часто всплывают запросы от редактора, формы комментариев, плагинов аналитики и блоков с динамическим контентом. Отдельно проверьте, нет ли интеграций, которые обращаются к REST с фронтенда без авторизации.
Что проверить вручную
- открывается ли
/wp-json/в браузере для гостя; - работает ли редактор записей и загрузка блоков в админке;
- нет ли ошибок в консоли JavaScript на страницах с формами и виджетами;
- используют ли плагины REST-маршруты для публичных данных;
- не завязана ли тема на запросы к
wp-jsonдля подгрузки контента.
Если вы не уверены, где именно ломается запрос, временно откройте страницу с проблемным блоком и посмотрите ответы сети. Ошибка 401, 403 или пустой JSON обычно сразу показывает, что ограничение слишком жёсткое.
Пошаговое решение через PHP
Самый предсказуемый вариант — запретить REST API для незалогиненных пользователей через фильтр rest_authentication_errors. Это не отключает REST целиком, а возвращает отказ только там, где пользователь не авторизован. Такой подход лучше, чем грубый запрет по URL на уровне сервера, потому что WordPress сам решает, кому можно работать с API.
<?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_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 403 )
);
} );Этот код лучше добавлять в мини-плагин или в functions.php дочерней темы, а не в родительскую тему. Тогда ограничение не пропадёт после обновления оформления.
Если нужно оставить часть маршрутов открытой
Иногда полностью закрывать REST для гостей нельзя: например, публичный API нужен для списка записей, а закрыть хочется только служебные маршруты. Тогда вместо общего запрета можно проверять конкретный маршрут через rest_pre_dispatch или разрешать только нужные namespace. Это уже более тонкая настройка и требует тестирования на вашем наборе плагинов.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) || is_user_logged_in() ) {
return $result;
}
$uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
if ( strpos( $uri, '/wp-json/wp/v2/posts' ) !== false ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
__( 'REST API закрыт для гостей.', 'textdomain' ),
array( 'status' => 403 )
);
} );Это пример, а не универсальная схема. Перед использованием нужно точно понимать, какие маршруты вы хотите оставить доступными, иначе легко открыть лишнее или, наоборот, закрыть нужное.
Сравнение подходов: плагин, код, сервер
| Подход | Плюсы | Минусы | Когда выбирать |
|---|---|---|---|
| Плагин безопасности | Быстро, без кода | Может конфликтовать с интеграциями, лишняя нагрузка | Если нужен быстрый старт и есть опыт тестирования плагинов |
| PHP-фильтр | Точно, прозрачно, без внешней зависимости | Нужно тестировать маршруты вручную | Если нужен контроль и понятное поведение |
| .htaccess / nginx | Режет запросы раньше WordPress | Легко сломать админку и легитимные запросы | Только если вы уверены в инфраструктуре и маршрутах |
Для большинства сайтов PHP-ограничение — самый безопасный компромисс. Оно не требует трогать веб-сервер и при этом оставляет WordPress возможность вернуть 403 осмысленно, а не просто отдать пустую страницу.
Проверка результата после внедрения
После правки откройте /wp-json/ в режиме инкогнито. Для гостя должен вернуться отказ, а не список маршрутов. Затем войдите в админку и проверьте редактор записей: загрузку блоков, сохранение черновика, предпросмотр и работу метабоксов, если они завязаны на REST.
Дальше откройте несколько страниц сайта и посмотрите консоль браузера. Если какой-то плагин ожидал публичный REST-ответ, вы увидите ошибки запросов или пустые данные. Это сигнал не «откатывать всё», а точечно вернуть нужный маршрут или заменить способ получения данных.
Мини-чек-лист проверки
- гость получает 403 на
/wp-json/; - авторизованный пользователь видит админку без ошибок;
- редактор блоков открывается и сохраняет записи;
- нет ошибок JavaScript на страницах с динамическими блоками;
- внешние интеграции не потеряли доступ к нужным маршрутам.
Частые ошибки и как их исправить
Закрыли REST через .htaccess и сломали всё подряд
Жёсткая блокировка по URL часто задевает не только публичные запросы, но и внутренние вызовы WordPress. Если после правки админка начала вести себя странно, уберите серверное правило и перенесите ограничение в PHP-фильтр.
Не проверили плагины, которые используют REST
Часть форм, конструкторов и SEO-плагинов обращается к REST API для подгрузки данных. Если после ограничения пропали блоки или перестали работать автосохранение и предпросмотр, значит, маршрут нужен именно этому плагину.
Оставили код в родительской теме
После обновления темы ограничение исчезнет. Для таких правок лучше использовать дочернюю тему или небольшой must-use плагин.
Сразу закрыли всё без теста в инкогнито
Проверка только под админом ничего не показывает: авторизованный пользователь и гость получают разные ответы. Тестировать нужно оба сценария.
Что делать, если REST нужен только частично
Если задача не в полном закрытии, а в снижении публичности, можно оставить доступ только к конкретным маршрутам, которые реально нужны сайту. Это лучше, чем пытаться «угадать» все исключения на уровне сервера. Для сложных сайтов полезно сначала составить список используемых namespace, а уже потом решать, что закрывать.
Когда на сайте много технических плагинов, иногда проще не писать собственные исключения, а использовать проверенный инструмент для чистки и отключения лишнего. Например, Clearfy Pro у WPShop закрывает часть типовых технических хвостов и помогает убрать лишнее без ручного расползания кода: https://wpshop.ru/plugins/clearfy. Но даже в этом случае логику доступа к REST лучше проверить отдельно.
Практика безопасности и производительности
Ограничение REST API само по себе не заменяет защиту от брутфорса, WAF или нормальную настройку ролей. Зато оно уменьшает поверхность атаки и убирает лишние публичные ответы, которые не нужны гостям. Если сайт активно использует динамические блоки, сначала замерьте поведение на staging, а уже потом переносите правку на боевой сервер.
И ещё один момент: не храните такие изменения в случайном сниппет-плагине без контроля версий. Для технических правок на WordPress лучше иметь либо мини-плагин в репозитории, либо хотя бы отдельный файл с понятной историей изменений. Тогда при конфликте с обновлением плагина вы быстро поймёте, где искать причину.