Nginx кэширует страницу с данными пользователя после истечения его cookie (кукиша)

logo

Nginx кэширует страницу с данными пользователя после истечения его cookie (кукиша) В сети куча примеров для настройки Nginx кэширования, тупая копипаста которых или же не работает вовсе или же работает, но не так как нужно (кэш файлов растёт, а эффекта = 0). Кэширование Nginx на CMS Joomla.

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

Невозможно было определить откуда ноги растут!;( Конфиг Nginx-а отшлифован и отлажен уже до такой степени, что дальше некуда - куда грешить было неясно... Начинаем копать-колупать...

Нынче рассматривается случай, когда Nginx кэширует всё как нужно, но когда некая cookie (кукиш) авторизированного пользователя истекает, то открытая ранее им страница (с данными профиля в боковой панели) посещённая снова (после истечения кукиша) кэшируется вместе с его данными профиля в боковой панели.

Т.е. мы успешно прошли авторизацию (валидность авторизации 3 часа), предварительно очистив кэш "rm -R /var/cache/nginx/pagecache/*" открыли любую статью на сайте, например "Бортовой журнал подземной лодки. О чем шептали корни.", видим статью, а в правой части экрана видим краткие данные своего профиля. Потом открываем в другом браузере, где нет авторизации, туже страницу "Бортовой журнал подземной лодки. О чем шептали корни." и всё ок. - там мы видим голую статью, которая успешно закэшировалась без чужих данных, для полной уверенности снова удаляем кэш "rm -R /var/cache/nginx/pagecache/*" и открываем туже страницу в браузере с авторизацией, а после в браузере без авторизации и опять же проблем не наблюдаем, замечательно!


ТЕПЕРЬ ВНИМАНИЕ ФОКУС: Страницу "Бортовой журнал подземной лодки. О чем шептали корни.", в том браузере где была авторизация, не закрываем и оставляем открытой, ждём когда авторизация истекает и теперь..., теперь чистим "rm -R /var/cache/nginx/pagecache/*" и сразу обновляем страницу, которая какого-то хрена кэшируется вместе с данными профиля (в правой боковой панели) уже неавторизированного пользователя - что за хрень? Парадокс?

Ну да не впадём же мы в уныние! Копаем-колупаем дальше... Такой парадокс наблюдаем в любом браузере! Хотя закэшировать то по идее должно бы страницу без данных профиля ибо кукиш то уже якобы должен то истечь. Решение о кэшировании или не кэшировании страницы nginx-ом принимается по факту наличия/отсутствия кукиша с именем activeProfile и местами неких параметров в строке запроса.

Берём браузер чистим кукиши, открываем девственную страницу и смотрим какие там кукиши устанавливаются для анонов, потом проходим авторизацию и опять смотрим кукиши которые появились новые или как изменились старые.

При попытке авторизации с пустыми логином и паролем, устанавливается кукиш так называемый Token со случайным именем (102d16838e890126ac58488e19aaad2d) и его значением (pf9g83h0ko6ap0uvul2tjekrg3). Этот Token связывает браузер пользователя с его сессией и не меняется независимо от успешности авторизации, имеет неограниченный срок жизни и удаляется только после нажатия на кнопку выхода из системы. Если после успешной авторизации изменить имя или значение Token-а, то мы сразу же потеряем доступ к своему акаунту.

Вот оно откуда растут ноги! Оказалось, что Token имеет неограниченное время жизни! После того как выдохся кукиш с именем activeProfile но не уничтожен Token связывающий браузер с сессией пользователя, то по сути сессия продолжает быть валидной и в браузер продолжают поступать данные авторизированного ранее пользователя - фича это или бага Joomla 1.5 и его компонента Jomsocial, пока не совсем ясно, но сдается мне, что это скорее бага!:), а нежели фича и на токен должно устанавливаться время жизни указываемое в переменной $lifetime конфиг. файла configuration.php.

Сей функционал, т.е. время жизни кукиша для Token-а реализуется PHP функцией session_set_cookie_params() в файле /libraries/joomla/session/session.php:

/**
* Set session cookie parameters
*
* @access private
*/
function _setCookieParams() {
    $cookie  =   session_get_cookie_params();
    if($this->_force_ssl) {
        $cookie['secure'] = true;
    }
    session_set_cookie_params( $cookie['lifetime'], $cookie['path'], $cookie['domain'], 
        $cookie['secure'] );
}

Итак..., бага обнаружена и сейчас будет беспощадно уничтожена модификацией /libraries/joomla/session/session.php до следующей кондиции:

/**
* Set session cookie parameters
*
* @access private
*/
function _setCookieParams() {
    $cookie =   session_get_cookie_params();
    if($this->_force_ssl) {
        $cookie['secure'] = true;
    }
    $jConfig  =& JFactory::getConfig();
    $lifetime  = $jConfig->getValue('lifetime');
    $cookie['lifetime'] = ($lifetime * 60);
    session_set_cookie_params( $cookie['lifetime'], $cookie['path'], 
        $cookie['domain'], $cookie['secure'] );
}

Теперь при авторизации у нас будет выставляться одинаковое время жизни для кукишей Token-а и activeProfile. Если в session_set_cookie_params время жизни будет установлено неверно, то при авторизации мы можем получать "Invalid Token", хотя сообщение "Invalid Token" может выдаваться и в других случаях, например при одновременной попытке авторизации в фронтэнде и бакэнде сайта или при устаревшем Token-е!

Также, кроме наличия кукиша activeProfile и установки аналогичного ей времени жизни для Token-а, дополнительно нужно добавить в файл /libraries/joomla/application/application.php функцию установки/удаления некоего кукиша, например с именем "jremember", а также функцию его удаления в /plugins/system/remember.php - это нужно для тех случаев, когда при входе было отмечено "Запомнить".

Итоги

Кэширование Nginx мощная штука и капитально снижает нагрузку на бакэнд сервера, но как показывает практика его использования, единой конфигурации/рецепта Nginx кэширования не существует и для каждой системы управления, в т.ч. CMS Joomla, нужна своя конфигурация Nginx с возможным допиливанием/модифицированием файлов движка, добавлением кукишей и т.д. и т.п..

Ссылки по теме

Рекомендуемый контент


Добавить комментарий

АХТУНГ! Все комменты модерасятся модерастом. Мессаги исключительно рекламного или оскорбительного содержания не публикуются, а поэтому злостным спамерам, пранкерам и прочей сетевой нечисти рекомендуем напрасно не тратить своего времени и удовлетворять свои больные фантазии на специализированных Интернет ресурсах! Разумная же критика, замечания, дополнения и хвалебные оды приветствуются, также допускается легкий флуд или троллинг :)


Защитный код
Обновить

Новое на форуме