Как ограничить открытые endpoint’ы REST API в WordPress без поломки админки

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

Ниже разберем не «выключить все», а нормальный рабочий сценарий: оставить то, что нужно редактору и фронтенду, и ограничить лишнее для гостей.

Когда REST API действительно стоит ограничивать

Сначала проверьте, что именно у вас открыто. Не каждый endpoint нужно закрывать. Например, Gutenberg и часть админки используют REST API постоянно. Если просто заблокировать /wp-json/ целиком, сломаются редактор, автосохранение, некоторые формы, поиск и плагины, которые получают данные через API.

Типичные признаки проблемы

  • в /wp-json/ видны маршруты, которые не нужны гостям;
  • в логах много запросов к REST API от ботов;
  • плагины безопасности показывают лишние публичные endpoint’ы;
  • на сайте есть кастомные маршруты, которые отдают служебные данные без проверки прав;
  • нужно убрать доступ к части API, но оставить редактор и авторизованные запросы.

Что не стоит делать

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

Диагностика: какие endpoint’ы доступны гостям

Проверка начинается с обычного запроса к корневому индексу REST API. Откройте /wp-json/ в браузере или выполните запрос из консоли. Если сайт отдает большой список маршрутов, это нормально. Важно понять, какие из них должны быть публичными, а какие — нет.

curl -I https://example.com/wp-json/

Если нужен более предметный осмотр, посмотрите конкретные маршруты. Например, часто публично доступны:

  • /wp-json/wp/v2/posts;
  • /wp-json/wp/v2/pages;
  • /wp-json/wp/v2/categories;
  • /wp-json/wp/v2/tags.

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

Рабочая схема: ограничить REST API только для гостей

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

Ниже пример, который блокирует доступ гостям ко всем REST-запросам, кроме нескольких разрешенных маршрутов. Такой вариант полезен, если вам нужно оставить публичный доступ только к отдельным endpoint’ам.

<?php
add_filter( 'rest_authentication_errors', function( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }

    if ( is_user_logged_in() ) {
        return $result;
    }

    $uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';

    $allowed = array(
        '/wp-json/',
        '/wp-json/oembed/1.0/embed',
    );

    foreach ( $allowed as $path ) {
        if ( str_contains( $uri, $path ) ) {
            return $result;
        }
    }

    return new WP_Error(
        'rest_forbidden',
        'REST API доступен только авторизованным пользователям.',
        array( 'status' => 401 )
    );
} );

Но у этого варианта есть важная оговорка: он слишком жесткий для большинства обычных сайтов. Если у вас есть публичный контент, блоки, встроенные формы или внешние сервисы, лучше ограничивать не весь API, а отдельные маршруты.

Точечная блокировка отдельных маршрутов

Если задача — убрать только чувствительные данные, удобнее использовать фильтр rest_endpoints. Он позволяет удалить конкретные маршруты из списка доступных endpoint’ов для гостей.

<?php
add_filter( 'rest_endpoints', function( $endpoints ) {
    if ( is_user_logged_in() ) {
        return $endpoints;
    }

    $blocked = array(
        '/wp/v2/users',
        '/wp/v2/comments',
    );

    foreach ( $blocked as $route ) {
        if ( isset( $endpoints[ $route ] ) ) {
            unset( $endpoints[ $route ] );
        }
    }

    return $endpoints;
} );

Этот способ лучше, если вам нужно скрыть пользователей, комментарии или служебные маршруты, но оставить публичные записи и страницы. Для большинства редакционных сайтов это более практично, чем тотальная блокировка.

Если нужен доступ только к своим кастомным маршрутам

Для собственных endpoint’ов правильнее проверять права внутри callback-функции через current_user_can(). Не полагайтесь только на то, что маршрут «не светится» в интерфейсе. Если endpoint возвращает служебные данные, ограничьте его явно.

<?php
register_rest_route( 'myplugin/v1', '/stats', array(
    'methods'  => 'GET',
    'callback' => function() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return new WP_Error( 'forbidden', 'Недостаточно прав.', array( 'status' => 403 ) );
        }

        return array(
            'status' => 'ok',
        );
    },
    'permission_callback' => '__return_true',
) );

Здесь важен не только permission_callback, но и реальная проверка внутри callback. Это снижает риск случайно открыть данные при доработках.

Сравнение подходов

ПодходЧто делаетМинусКогда использовать
Полная блокировка REST APIЗакрывает все запросы для гостейЛегко ломает редактор и фронтендТолько для закрытых внутренних сайтов
rest_authentication_errorsБлокирует запросы до выполненияНужно аккуратно составлять исключенияКогда надо ограничить доступ для гостей
rest_endpointsУбирает отдельные маршрутыНе защищает уже известные кастомные URL без проверки правКогда нужно скрыть только часть API

Пошаговое внедрение без сюрпризов

  1. Сделайте резервную копию файла functions.php или вынесите код в мини-плагин.
  2. Проверьте, какие маршруты реально используются на сайте и в админке.
  3. Сначала ограничьте только самые чувствительные endpoint’ы.
  4. Протестируйте вход в редактор, автосохранение, формы и AJAX-запросы.
  5. Посмотрите ответы 401 и 403 в браузере и в логах.
  6. Если все работает, расширяйте список ограничений постепенно.

Как проверить, что решение сработало

Проверка должна быть не «страница открылась», а конкретной. Смотрите на ответы API с разных ролей.

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

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

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

Блокируют весь /wp-json/

Так делают чаще всего, когда хотят «закрыть API». В результате ломается редактор и часть плагинов. Исправление простое: верните доступ к нужным маршрутам и ограничьте только чувствительные endpoint’ы.

Проверяют только URL, но не права пользователя

Если кастомный маршрут отдает данные, а внутри callback нет проверки current_user_can(), маршрут остается уязвимым. Исправление: добавьте явную проверку прав и возвращайте WP_Error с кодом 403.

Не тестируют фронтенд после изменений

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

Ставят блокировку в тему, а потом теряют ее при обновлении

Если код лежит в functions.php, он исчезнет при смене темы. Для таких задач лучше мини-плагин или mu-plugin. Это надежнее и проще сопровождать.

Что учесть по безопасности и производительности

Ограничение REST API не заменяет нормальную защиту сайта. Если на проекте есть чувствительные данные, дополнительно проверьте права на кастомные маршруты, отключите лишние публичные endpoint’ы плагинов и не публикуйте служебные данные в ответах API.

С точки зрения производительности точечная блокировка полезнее, чем грубое отключение. Вы не ломаете рабочие сценарии и не создаете лишние обходные костыли на фронтенде. Если у вас много технических дублей, лишних маршрутов и служебных страниц, имеет смысл отдельно пройтись по настройкам SEO и чистке сайта — например, через Clearfy Pro, если нужен набор практических инструментов для удаления дублей и технической оптимизации.

Главное правило простое: сначала выясните, какие endpoint’ы реально нужны, потом ограничивайте только лишнее. В WordPress это почти всегда безопаснее, чем пытаться выключить все одним движением.

Автоматическое удаление старого кеша в WordPress: практическое руководство
18.12.2025
Как создать динамические блоки с ключевыми словами в WordPress
26.01.2026
Как установить уникальные виджеты в WordPress для каждого шаблона
07.04.2026
Как запретить индексацию категорий в WordPress
17.01.2026
Как добавить автоподсказки в поиск WordPress
08.03.2026