Почему REST API WordPress возвращает 403 при запросах с Authorization header

Если REST API в WordPress отвечает 403 Forbidden только тогда, когда запрос идет с заголовком Authorization, проблема обычно не в самом WordPress, а в связке серверного прокси, WAF, плагинов безопасности или конфигурации PHP-FPM/Apache. Это типичный сценарий для интеграций с внешними сервисами, мобильными приложениями, headless-фронтендом и кастомными эндпоинтами.

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

Как выглядит проблема на практике

Обычно симптомы такие:

  • /wp-json/ открывается в браузере, но POST/GET-запросы с токеном получают 403;
  • без заголовка Authorization тот же эндпоинт отвечает нормально;
  • в логах сервера виден 403, но WordPress-ошибка не формируется;
  • в админке все работает, а внешняя интеграция ломается;
  • после установки плагина безопасности или включения CDN проблема появляется внезапно.

Важно не путать этот кейс с 401 Unauthorized. 401 обычно означает, что аутентификация не прошла. 403 чаще говорит о том, что запрос отрезали раньше, чем WordPress успел его обработать.

Диагностика: где именно теряется Authorization

Начинать стоит не с правки кода, а с проверки цепочки запроса. В WordPress сам REST API не блокирует Authorization как класс. Чаще всего заголовок теряется на уровне веб-сервера или прокси.

1. Проверьте, доходит ли заголовок до PHP

Самый быстрый способ — временно вывести заголовки в mu-plugin или в тестовый плагин. Для продакшена так не оставляют, но для диагностики это полезно.

<?php
/**
 * Plugin Name: Header Debug
 */
add_action('init', function () {
    if (!defined('REST_REQUEST') || !REST_REQUEST) {
        return;
    }

    if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
        error_log('HTTP_AUTHORIZATION: ' . $_SERVER['HTTP_AUTHORIZATION']);
    } elseif (function_exists('getallheaders')) {
        $headers = getallheaders();
        if (!empty($headers['Authorization'])) {
            error_log('Authorization: ' . $headers['Authorization']);
        }
    }
});

Если в логах пусто, а клиент точно отправляет заголовок, значит он отрезается до WordPress.

2. Посмотрите ответ сервера без WordPress-слоя

Проверьте запрос через curl. Это помогает отделить проблему клиента от проблемы сервера.

curl -i https://example.com/wp-json/wp/v2/users/me \
  -H 'Authorization: Bearer YOUR_TOKEN'

Если в ответе сразу 403 и в access/error log нет следов обработки WordPress, ищите блокировку в Nginx, Apache, ModSecurity, Cloudflare или другом WAF.

3. Проверьте плагины безопасности и кеширования

Некоторые плагины безопасности фильтруют заголовки или режут REST-запросы по сигнатурам. Особенно это заметно, если включены:

  • ограничение REST API для неавторизованных пользователей;
  • защита от XML-RPC и «подозрительных» заголовков;
  • скрытие wp-json или жесткая фильтрация запросов к нему;
  • firewall-режим с блокировкой bearer-токенов.

Если после временной деактивации плагина проблема исчезает, это уже не гипотеза, а рабочая точка входа.

Что исправлять в первую очередь

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

1. Передайте Authorization в PHP

На Nginx и некоторых конфигурациях PHP-FPM заголовок Authorization не попадает в $_SERVER автоматически. Для Nginx часто помогает явная передача заголовка в FastCGI.

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTP_AUTHORIZATION $http_authorization;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}

Для Apache иногда нужен модуль mod_rewrite или корректная передача заголовков в связке с PHP-FPM. Если используется прокси, проверьте, не обнуляет ли он Authorization на уровне upstream.

2. Если стоит Cloudflare или другой WAF, проверьте правила

WAF может блокировать запросы с токенами, если они похожи на автоматизированный трафик. Ищите в логах события, связанные с:

  • REST endpoint;
  • заголовком Authorization;
  • подозрительными user-agent;
  • rate limiting для API-путей.

Иногда достаточно добавить исключение для /wp-json/* или конкретного маршрута, если он используется только вашим приложением.

3. Уберите конфликтующий фильтр в теме или плагине

Если в проекте есть кастомный код, проверьте фильтры, которые могут вмешиваться в REST:

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

    // Нельзя бездумно возвращать WP_Error здесь — это ломает авторизацию.
    return $result;
});

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

Сравнение подходов: сервер, плагин или код

ПодходКогда подходитПлюсыМинусы
Правка Nginx/ApacheЗаголовок теряется до PHPРешает причину, а не симптомНужен доступ к конфигу сервера
Исключение в WAF/CDN403 идет от защитыБыстро снимает блокировкуНужно аккуратно не ослабить защиту целиком
Правка плагина/темыКонфликт в кастомном кодеТочечное исправлениеТребует ревизии кода и теста регрессий

Пошаговое решение без лишнего риска

  1. Сделайте копию конфигурации сервера и списка активных плагинов.
  2. Проверьте, доходит ли Authorization до PHP через логирование.
  3. Если заголовок теряется, добавьте его передачу в Nginx или проверьте прокси.
  4. Если заголовок доходит, временно отключите плагины безопасности и кеша.
  5. Повторите запрос через curl и через реальный клиент.
  6. Если виноват кастомный код, найдите фильтры rest_authentication_errors и связанные проверки прав.

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

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

Проверка должна быть не только визуальной. Нужны минимум три сигнала:

  • curl возвращает ожидаемый код ответа, а не 403;
  • в логах PHP появляется HTTP_AUTHORIZATION или заголовок доступен в обработчике;
  • реальная интеграция, которая раньше падала, проходит аутентификацию и получает данные.

Если вы исправляли серверную конфигурацию, перезапустите PHP-FPM и веб-сервер, затем повторите тест. Если меняли плагин безопасности, проверьте не только один эндпоинт, а несколько маршрутов REST API, которые используются в проекте.

Частые ошибки и почему они ломают REST API

  • Проверяют только браузер. Браузерный запрос может идти без нужного заголовка или сессии, поэтому проблема маскируется.
  • Отключают все плагины навсегда. Это не диагностика, а потеря контроля. Нужен поэтапный тест.
  • Добавляют исключение для всего /wp-json/ без необходимости. Так можно ослабить защиту шире, чем требуется.
  • Правят WordPress-код вместо сервера. Если заголовок не доходит до PHP, никакой фильтр в WordPress не поможет.
  • Не учитывают CDN. Запрос может блокироваться на edge-уровне, а в серверных логах его вообще не будет.

Безопасность и производительность: что не стоит делать

Не отключайте REST API глобально только ради обхода ошибки. Это ломает интеграции, редактор, мобильные сценарии и может создать ложное ощущение безопасности. Лучше ограничить доступ точечно: по маршруту, по IP, по токену или по роли, если это действительно нужно проекту.

Если у вас много технических дублей, мусорных архивов и лишних точек входа в индексацию, имеет смысл отдельно навести порядок в SEO-слое и служебных страницах. Для таких задач иногда используют Clearfy Pro: он помогает убрать часть технического шума и дублирующих сущностей, но проблему 403 на REST API он сам по себе не решает.

Когда стоит смотреть в сторону кастомной аутентификации

Если внешний сервис работает нестабильно через cookie-auth или basic auth, лучше перейти на более предсказуемую схему: application passwords, OAuth-подобный шлюз или собственный токен-слой с жесткой проверкой маршрутов. Важно, чтобы способ аутентификации соответствовал вашему стеку и не зависел от случайных особенностей прокси.

Для проектов, где REST API — часть основного продукта, полезно документировать:

  • какие эндпоинты доступны извне;
  • какой тип авторизации используется;
  • какие заголовки обязательны;
  • какие правила WAF/CDN должны быть исключены;
  • какие плагины могут влиять на маршрут.

Такой список экономит часы, когда 403 появляется после обновления сервера, плагина безопасности или CDN-правил.

Почему REST API WordPress возвращает 403 при запросах с Authorization header
12.09.2026
Как убрать дубли title, description и canonical в WordPress
16.09.2026
WordPress XML-RPC 403 и 404: как отключить, проверить и не сломать доступ к сайту
20.09.2026
×
Прокачай свой сайт WordPress!

WordPress

-20% на премиум темы и плагины

Создай сайт своей мечты ⋙