Как закрыть REST API от посторонних запросов в WordPress

REST API в WordPress часто оставляют открытым по умолчанию, а потом удивляются лишним запросам к /wp-json/, утечке служебных данных и шуму в логах. Полностью отключать API обычно не нужно: Gutenberg, мобильные приложения и часть плагинов завязаны на него. Задача практичнее — ограничить доступ там, где он реально не нужен, и не сломать админку, редактор и публичные интеграции.

Когда проблема действительно есть

Сначала стоит понять, что именно вас беспокоит. Не каждый запрос к REST API — это атака или ошибка. Но если в логах много обращений к /wp-json/wp/v2/users, если боты массово дергают эндпоинты без пользы, если на сайте есть API-утечки через плагины или кастомные маршруты, тогда ограничение доступа оправдано.

Типичные признаки

  • в access-логах много запросов к /wp-json/ от одних и тех же IP;
  • появляются запросы к /wp-json/wp/v2/users и /wp-json/wp/v2/comments без явной причины;
  • на сайте есть публичные данные, которые не должны быть доступны без авторизации;
  • после установки плагина с API-эндпоинтами нагрузка выросла, а пользы от них нет;
  • в админке или редакторе возникают ошибки, если кто-то уже пытался «рубить» REST API через disable_rest_api без проверки.

Что именно закрывать, а что оставить

Полное отключение REST API — грубый вариант. Он может сломать блоковый редактор, предпросмотр, некоторые формы, интеграции с внешними сервисами и плагины, которые используют стандартные маршруты WordPress. Обычно безопаснее ограничить только публичные запросы к чувствительным маршрутам и оставить доступ авторизованным пользователям.

ПодходЧто делаетРиск
Плагин безопасностиБлокирует часть REST-запросов без кодаМожет конфликтовать с другими правилами и скрывать причину проблемы
Код в functions.php или MU-плагинеТочечно ограничивает нужные маршрутыНужно аккуратно тестировать после обновлений
Полное отключение APIЛомает доступ ко всем маршрутам для гостейВысокий риск поломки редактора и плагинов

Диагностика: какие маршруты реально используются

Перед изменениями посмотрите, какие REST-эндпоинты дергаются на вашем сайте. Если у вас есть доступ к логам веб-сервера, это самый надежный способ. В WordPress можно также временно включить логирование на уровне плагина или отладочного файла, но не оставляйте WP_DEBUG включенным на боевом сайте надолго.

Что проверить вручную

  • откройте https://example.com/wp-json/ и посмотрите, какие маршруты доступны;
  • проверьте, не используются ли кастомные эндпоинты плагинов;
  • зайдите в редактор записей и убедитесь, что он работает без ошибок;
  • посмотрите, не завязаны ли на REST формы, поиск, фильтры или фронтенд-виджеты.

Если вы не уверены, лучше начать с мягкого ограничения: закрыть только чувствительные маршруты для гостей, а не весь API целиком.

Пошаговое решение через код

Самый предсказуемый способ — добавить фильтр rest_authentication_errors и запретить доступ к выбранным маршрутам для неавторизованных пользователей. Такой подход не ломает весь API и позволяет оставить рабочими те части, которые нужны редактору и плагинам.

<?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'] ) : '';

    // Закрываем только чувствительные маршруты.
    $blocked_routes = array(
        '/wp-json/wp/v2/users',
        '/wp-json/wp/v2/comments',
    );

    foreach ( $blocked_routes as $route ) {
        if ( strpos( $request_uri, $route ) !== false ) {
            return new WP_Error(
                'rest_forbidden',
                __( 'REST API restricted for this route.', 'textdomain' ),
                array( 'status' => 403 )
            );
        }
    }

    return $result;
} );

Этот вариант простой, но есть нюанс: он опирается на REQUEST_URI. Для точечной защиты этого достаточно, если вы понимаете, какие URL хотите закрыть. Если нужен более строгий контроль, лучше проверять маршрут через сам объект запроса.

Более аккуратный вариант — использовать rest_pre_dispatch и смотреть на маршрут запроса. Так вы не зависите от структуры URI и можете точнее обрабатывать конкретные эндпоинты.

<?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 $blocked_route ) {
        if ( strpos( $route, $blocked_route ) === 0 ) {
            return new WP_Error(
                'rest_forbidden',
                __( 'Access denied.', 'textdomain' ),
                array( 'status' => 403 )
            );
        }
    }

    return $result;
}, 10, 3 );

Если нужно закрыть REST API полностью для гостей

Иногда задача именно такая: сайт не использует публичные REST-запросы, а редактор и админка работают только для авторизованных пользователей. Тогда можно отключить API для неавторизованных посетителей, но делать это нужно осторожно и после теста на staging.

<?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_not_allowed',
        __( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
        array( 'status' => 401 )
    );
} );

Такой код лучше размещать в MU-плагине, а не в functions.php активной темы. Тогда защита не исчезнет при смене темы.

Когда этот вариант не подходит

  • если сайт использует фронтенд-редактор или headless-сценарий;
  • если формы, поиск или фильтры обращаются к REST API;
  • если у вас есть мобильное приложение или внешняя интеграция;
  • если редакторы жалуются на ошибки при сохранении блоков.

Проверка результата после внедрения

После изменения правил не ограничивайтесь открытием главной страницы. Проверьте несколько сценариев отдельно: публичный доступ, редактор, авторизованный доступ и проблемные маршруты.

  • откройте /wp-json/ в браузере без авторизации;
  • проверьте /wp-json/wp/v2/users и убедитесь, что доступ закрыт;
  • войдите в админку и откройте редактор записи;
  • сохраните запись и проверьте, нет ли ошибок в консоли браузера;
  • посмотрите access-лог: нужные маршруты должны отдавать 403 или 401, а не 200.

Если у вас есть мониторинг, полезно отдельно проверить, не выросло ли число ошибок rest_forbidden после внедрения. Это покажет, не задели ли вы легитимные запросы.

Частые ошибки и как их исправить

Отключили REST API целиком и сломали редактор

Такое часто происходит, когда используют слишком агрессивный код или плагин, который блокирует все маршруты без исключений. Решение — убрать глобальный запрет и перейти к списку конкретных маршрутов.

Проверяют только URL, а не маршрут

Если фильтрация завязана на строку в REQUEST_URI, можно промахнуться мимо варианта с параметрами, прокси или нестандартной структурой URL. Для точности лучше использовать $request->get_route().

Размещают код в теме

При смене темы защита исчезает. Для системных ограничений лучше использовать MU-плагин или небольшой собственный плагин.

Блокируют API, но не проверяют плагины

Некоторые плагины используют REST API для фронтенда, статистики, форм или интеграций. После изменений нужно пройтись по ключевым пользовательским сценариям, а не только по главной странице.

Практические советы по безопасности и производительности

Если цель — не просто закрыть API, а уменьшить поверхность атаки, не ограничивайтесь одним фильтром. Посмотрите на сопутствующие вещи: отключите лишние публичные маршруты в плагинах, уберите ненужные XML-RPC-интеграции, проверьте права пользователей и не храните секреты в открытых endpoint-ах.

  • не отключайте REST API без теста на копии сайта;
  • не закрывайте все маршруты, если сайт использует Gutenberg;
  • не ставьте несколько плагинов безопасности, которые дублируют одни и те же ограничения;
  • после обновления WordPress и плагинов повторно проверьте маршруты;
  • если нужен быстрый способ убрать дубли и лишние служебные элементы, посмотрите на Clearfy Pro, но все равно тестируйте совместимость с вашим стеком.

Для сайтов, где REST API используется только частично, такой точечный подход обычно надежнее, чем попытка «выключить всё и забыть». Он оставляет рабочими нужные сценарии и дает понятный контроль над тем, что именно доступно извне.

Как закрыть REST API от посторонних запросов в WordPress
25.08.2026