Диагностика проблемы кэширования REST API с авторизацией
WP REST API активно используется для создания динамичных интерфейсов и интеграций. Однако стандартные кэширующие плагины, включая WP Super Cache, часто не учитывают индивидуальные куки и заголовки авторизации, что приводит к возврату одинаковых ответов для разных пользователей, либо к неактуальным данным.
Типичные симптомы:
- Пользователь получает данные другого пользователя или устаревшие данные.
- Ошибка авторизации при запросах к API с кэшированием.
- Невозможность кэшировать запросы с уникальными параметрами авторизации.
Причина проблемы
WP Super Cache кэширует страницы по URL, не учитывая заголовки авторизации или куки, которые изменяют контент REST API. В результате, кэш не разделяет ответы для разных пользователей, вызывая рассинхронизацию и ошибки.
Пошаговое решение: как кэшировать REST API с авторизацией и куками
1. Определяем уникальность кэша по кукам
Чтобы кэш учитывал авторизацию, нужно добавить куки в ключ кэша. WP Super Cache поддерживает фильтр cache_key, который позволяет расширить ключ кэша.
add_filter('cache_key', 'add_auth_cookie_to_cache_key', 10, 2); function add_auth_cookie_to_cache_key($key, $uri) { if (strpos($uri, '/wp-json/') !== false) { $auth_cookie = isset($_COOKIE[LOGGED_IN_COOKIE]) ? $_COOKIE[LOGGED_IN_COOKIE] : ''; $key .= md5($auth_cookie); } return $key;}Этот код добавляет в ключ кэша хеш куки авторизации, что разделит кэш для разных пользователей.
2. Исключаем из кэширования неавторизованных запросов с нестандартными заголовками
Если REST API получает нестандартные заголовки авторизации (например, Bearer токен), то кэшировать такие запросы можно только с дополнительной логикой. В простом случае лучше исключить такие запросы из кэша.
add_filter('supercache_cache_reject_uri', 'reject_rest_api_with_auth_headers'); function reject_rest_api_with_auth_headers($reject) { if (strpos($_SERVER['REQUEST_URI'], '/wp-json/') !== false) { $headers = getallheaders(); if (!empty($headers['Authorization'])) { $reject = true; } } return $reject;}3. Добавляем заголовки для кэширования и очистки кэша при изменениях
Для корректного обновления кэша важно сбрасывать кэш REST API при изменении данных:
add_action('save_post', function($post_id) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (wp_is_post_revision($post_id)) return; if (function_exists('wp_cache_clear_cache')) { wp_cache_clear_cache(); } // Или специфичные функции очистки WP Super Cache if (function_exists('wp_cache_clear_cache_group')) { wp_cache_clear_cache_group('supercache'); }}, 10, 1);Проверка работы решения
1. Авторизуйтесь под разными пользователями и выполните запросы к REST API, например:
curl -H "Cookie: wordpress_logged_in_HASH=your_cookie" https://example.com/wp-json/wp/v2/posts2. Проверьте, что ответы различаются, если меняются куки авторизации.
3. Убедитесь, что при обновлении поста кэш REST API сбрасывается (проверьте время ответа и содержимое).
Частые ошибки и способы их исправления
- Кэш не разделяет пользователей: проверьте, что кука авторизации добавляется в ключ кэша. Возможно, имя куки отличается (LOGGED_IN_COOKIE — константа WordPress).
- REST API с Bearer токенами не кэшируется: для таких запросов рекомендуется отключать кэш, чтобы избежать ошибок.
- Кэш не сбрасывается после обновления контента: убедитесь, что хуки
save_postи другие события очищают кэш, либо реализуйте собственные функции очистки. - Производительность падает из-за слишком большого количества ключей кэша: учитывайте, что добавление куки в ключ кэша увеличивает количество кэшированных версий. Оптимизируйте время жизни и очистку кэша.
Практические советы по безопасности и производительности
- Не кэшируйте REST API запросы с чувствительными заголовками, например, токенами авторизации в заголовках — это может привести к утечке данных.
- Используйте серверные кэши (Redis, Memcached) для снижения нагрузки при большом числе разных ключей.
- Периодически проверяйте размер папки кэша и очищайте устаревшие данные, чтобы не переполнять диск.
- Для REST API с открытыми данными используйте кэширование без учёта куки, чтобы максимизировать отдачу.
Сравнение подходов к кэшированию REST API с авторизацией
| Метод | Плюсы | Минусы |
|---|---|---|
| Кэширование по URL без учёта куки | Простая настройка, меньше ключей кэша | Нет разделения данных для разных пользователей, ошибки безопасности |
| Добавление куки в ключ кэша (фильтр cache_key) | Разделение кэша по пользователям, актуальные данные | Увеличение количества ключей, больше нагрузки на диск |
| Отключение кэша для запросов с заголовками авторизации | Безопасность, корректность данных | Потеря выгоды от кэширования для таких запросов |