Как отключить REST API для неавторизованных в WordPress без поломки редактора и внешних интеграций

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

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

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

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

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

Если у вас есть фронтенд на React/Vue, мобильное приложение, интеграция с CRM или автоматизация через REST, закрывать API целиком не нужно. В таком случае ограничивают только публичные маршруты или добавляют авторизацию.

Диагностика: что именно сейчас открыто

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

Проверка через браузер и curl

Проверьте несколько адресов:

https://example.com/wp-json/
https://example.com/wp-json/wp/v2/posts
https://example.com/wp-json/wp/v2/users

Для быстрой проверки из консоли удобно использовать curl:

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

Если ответ 200 OK и JSON отдается без входа в админку, маршрут публичный. Для некоторых сайтов это допустимо, но если вы не хотите светить структуру контента, лучше ограничить доступ.

Что нельзя ломать

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

Пошаговое решение: ограничить REST API для гостей

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

<?php
add_filter( 'rest_authentication_errors', function ( $result ) {
    // Если уже есть ошибка аутентификации, не перезаписываем её.
    if ( ! empty( $result ) ) {
        return $result;
    }

    // Авторизованным пользователям REST нужен для редактора и админки.
    if ( is_user_logged_in() ) {
        return $result;
    }

    // Разрешаем только базовый индекс, если он нужен для диагностики.
    $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
    if ( strpos( $request_uri, '/wp-json/' ) === 0 && $request_uri === '/wp-json/' ) {
        return $result;
    }

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

Код можно добавить в functions.php дочерней темы, но для технически аккуратного проекта лучше вынести его в небольшой mu-plugin. Тогда он не пропадет при смене темы.

Вариант через mu-plugin

Создайте файл wp-content/mu-plugins/restrict-rest-api.php и положите туда код. Если папки mu-plugins нет, создайте её вручную.

<?php
/**
 * Plugin Name: Restrict REST API for guests
 */

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' => 401 )
    );
} );

Этот вариант проще сопровождать: код не зависит от темы, а отключение сводится к удалению одного файла.

Если нужно закрыть только часть маршрутов

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

<?php
add_filter( 'rest_endpoints', function ( $endpoints ) {
    if ( is_user_logged_in() ) {
        return $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, сначала протестируйте на staging-окружении.

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

ПодходЧто делаетПлюсыМинусы
Полная блокировка для гостейЗакрывает REST API для неавторизованныхПросто, быстро, снижает шумМожет сломать публичные интеграции
Ограничение отдельных маршрутовСкрывает только выбранные эндпоинтыТочнее, меньше рисковНужно знать зависимости плагинов
Оставить API и настроить авторизациюНе закрывает API, но требует токены/кукиПодходит для интеграций и headlessСложнее в поддержке

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

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

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

Для быстрой проверки статуса можно использовать:

curl -i https://example.com/wp-json/wp/v2/posts

Если вы ограничивали только отдельные маршруты, проверьте именно их. Не полагайтесь на один запрос к индексу /wp-json/: он не показывает, что происходит с конкретными endpoint'ами.

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

Сломали Gutenberg у редакторов

Обычно это происходит, когда блокировка применяется ко всем запросам без учета авторизации. Решение простое: не ограничивайте REST для вошедших пользователей. Если проблема уже появилась, временно отключите код и проверьте, не добавлен ли он в тему вместо mu-plugin.

Закрыли API, но JSON всё равно доступен

Некоторые плагины или серверные правила могут отдавать кешированную версию ответа. Очистите кеш плагина, серверный кеш и CDN. Если используется Nginx или Cloudflare, проверьте, не кэшируется ли /wp-json/ на уровне прокси.

Появились ошибки у внешнего сервиса

Значит, сервис действительно использовал REST без авторизации. В этом случае не стоит «чинить» проблему полным открытием API. Лучше выделить отдельный маршрут, настроить токен или использовать прикладную авторизацию, если сервис это поддерживает.

Ограничение добавили в тему, а потом забыли

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

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

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

  • не кэшируйте ответы REST без понимания, какие данные там отдаются;
  • проверьте, не индексируются ли JSON-URL в поиске через внешние ссылки и sitemap;
  • убедитесь, что сервер не отдает лишние заголовки и не раскрывает версию WordPress;
  • если сайт большой, тестируйте изменения на копии, а не на боевом домене;
  • после правки кода всегда проверяйте админку, редактор и формы обратной связи.

Если вам нужен более широкий набор технических настроек для чистки WordPress от дублей и лишних служебных запросов, удобно держать всё в одном месте. В таких задачах часто используют Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но даже с плагином полезно понимать, какой именно маршрут вы закрываете и почему.

Если нужен более мягкий режим

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

Практически это сводится к двум вопросам: кто должен иметь доступ и какие маршруты действительно нужны. Если ответов нет, начинайте с staging-копии и включайте ограничение постепенно, а не одним большим коммитом.

Как отключить XML-RPC pingback в WordPress без поломки внешних сервисов
10.09.2026
Как закрыть страницы поиска WordPress от индексации и убрать дубли в выдаче
04.09.2026
Как отключить ревизии в WordPress и ограничить автосохранение без потери удобства редактирования
17.09.2026
Как закрыть архивы авторов от индексации в WordPress без удаления страниц и дублей
27.09.2026
Как отключить emoji и дублирующие скрипты в WordPress без поломки редактора и фронтенда
07.09.2026