Почему кэширование WP REST API с авторизацией и куками — сложная задача?
WP REST API часто используется для динамического взаимодействия фронтенда и бэкенда в WordPress, особенно при создании SPA (Single Page Application) или кастомных интерфейсов. При этом запросы часто содержат авторизационные куки, определяющие доступ к персонализированному контенту.
Автоматическое кэширование таких запросов плагинами типа WP Super Cache или другими серверными кэшами может привести к выдаче устаревших или чужих данных, так как ответ зависит от состояния сессии пользователя.
Диагностика проблемы
Проверьте, кэшируются ли REST API запросы, требующие авторизации, без учёта куков:
- Откройте инструменты разработчика браузера (F12) на вкладке Network.
- Сделайте REST API запрос, например, к
/wp-json/wp/v2/users/meили другому авторизованному эндпоинту. - Проверьте заголовки ответа: если присутствуют заголовки кэширования (Cache-Control), и ответ одинаков для разных пользователей — это признак ошибки.
- Проверьте, возвращается ли правильный пользовательский контент.
Пошаговое решение: как корректно кэшировать WP REST API с авторизацией и куками
1. Отключаем кэширование REST API для авторизованных запросов
Большинство кэширующих плагинов по умолчанию отключают кэширование для авторизованных пользователей. Если нет — добавьте в functions.php вашей темы или в плагин следующий код:
add_filter('wp_super_cache_is_cacheable', function($cacheable) {
if (defined('REST_REQUEST') && REST_REQUEST && is_user_logged_in()) {
return false; // Не кэшировать REST API запросы для авторизованных
}
return $cacheable;
});2. Кэширование публичных REST API с учётом GET-параметров
Для публичных запросов без авторизации кэширование полезно, но нужно учитывать уникальность URL с параметрами. WP Super Cache уже кэширует по URL. Чтобы проверить и улучшить, можно:
- Убедиться, что все параметры передаются в URL, а не в теле запроса.
- Включить кэширование REST API: убрать фильтр, если он есть.
3. Кэширование REST API с авторизацией через JWT или OAuth
Если используете авторизацию через JWT, куки отсутствуют, и кэшировать ответы с разными токенами можно, если добавлять токен в ключ кэша. Для этого пропишите кастомное кеширование, например:
function custom_cache_key_for_rest() {
if (defined('REST_REQUEST') && REST_REQUEST) {
$headers = getallheaders();
$token = isset($headers['Authorization']) ? $headers['Authorization'] : '';
return md5($_SERVER['REQUEST_URI'] . $token);
}
return false;
}
add_filter('wp_super_cache_cache_key', 'custom_cache_key_for_rest');Проверка результата после внедрения
После внесения изменений проверяйте:
- Авторизованный пользователь делает REST API запрос — ответ не кэшируется, возвращается актуальная информация.
- Анонимный пользователь получает кэшированный ответ с учётом URL.
- Для JWT авторизации ответ кэшируется индивидуально по токену.
- Проверяйте заголовки ответа:
Cache-Control: no-cache, privateдля авторизованных иCache-Control: max-age=...для публичных.
Частые ошибки и как их исправить
- Кэширование авторизованных пользователей: приводит к выдаче чужих данных — отключайте кэш для
is_user_logged_in()иREST_REQUEST. - Игнорирование куков: некоторые плагины кэшируют без учёта куков, что ломает персонализацию. Проверьте, что куки используются для формирования ключа кэша.
- Неправильная настройка заголовков: отсутствие или неправильные Cache-Control могут мешать браузерам и прокси корректно работать с кэшем.
- Кэширование POST-запросов: REST API использует POST для изменений — кэшировать их нельзя.
Практические советы по безопасности и производительности
- Отключайте кэширование для всех REST API запросов, изменяющих данные (POST, PUT, DELETE).
- Для GET-запросов с авторизацией используйте индивидуальные ключи кэша, учитывающие токены или куки.
- Регулярно очищайте кэш после обновления данных через хуки
save_post,profile_updateи т.п. - Используйте инструменты мониторинга и дебага (например, Query Monitor) для отслеживания кэширования REST API.
Сравнение подходов к кэшированию REST API
| Метод | Преимущества | Недостатки | Пример кода |
|---|---|---|---|
| Отключение кэша для авторизованных | Простота, безопасность данных | Повышенная нагрузка на сервер | add_filter('wp_super_cache_is_cacheable', ...) |
| Кэширование с ключом по токену | Снижение нагрузки, персонализация | Сложность реализации, требует JWT | add_filter('wp_super_cache_cache_key', ...) |
| Кэширование только публичных GET-запросов | Максимальная производительность | Отсутствие персонализации | Включение стандартного кэша |