Использование кукисов, проблемы кеширования nginx

Цель данной заметки:
Решить проблему кеширования на уровне nginx.

Предисловие:
Кешировать можно все страницы на 10-60 минут для не залогиненных пользователей.
Проверять залогиненных пользователя можно по куке (LS — key, а в AltoCMS — user_key).

Используя LS 1.0.3/Alto 0.9.7.1 обнаружил особенности работы движка:
1. Всем (залогиненным и нет) пользователям выдается кука с идентификатором сессии. Она используется при открытии модальных окон, который подтягивают контент с сервера.
Это создает проблему в случае включения кеширования nginx-ом страниц для не залогиненных пользователей.
При попытке открыть контент в модальном окне происходит проверка сервером правильности идентификатора сессии.
Примеры:
http://sla.kiev.ua/video/ (здесь отключено кеширование, поэтому все работает)
http://sla.kiev.ua/tec/item/planer-l-13-blanik.html Закладка «Видео». Тут кеширование включено и видео в модальном окне не открывается.
Подскажите, как вообще избавиться от сессии для пользователя?

2. Залогиненным пользователям выдается выдается кука key. А только что зарегистрировавшимся — нет.
В результате пользователь зарегистрировался, тут же автоматом залогинился и не получил куки. При включенном кешировании это ломает всю работу сайта для этого пользователя.
Этот баг достался Альто от LS.
Можно воспроизвести зарегистрировавшись на моем сайте sla.kiev.ua
Подскажите, как бы его пофиксить или обойти?

Похожие статьи

  • Установить Nginx на Centos7
    Требуется на VPS сервере установить Nginx и обновить PHP на Centos 7. P.s. сам пробовал по мануалам, с конфигами и директориями не разобрался.
  • Дополнительный запрос к каждому топику
    Приветствую, сообщество и разработчики AltoCMS. Поясните, пожалуйста, один момент. У меня при включенном кеше на главной странице при 10 выведенных топиках (без фото, только название и одно доп.поле), судя по...
  • Nginx ограничение нагрузки
    Вещь о которой я хочу написать довольно тривиальна, но вдруг кому-то будет полезна. В Nginx есть модуль ngx_http_limit_req_module. Данный модуль позволяет ограничивать количество и частоту запросов к сайту с одного...
  • Makersbay.ru – каталог 3d моделей для 3d принтера
    Мне всегда нравилось делать что-то своими руками и мастерить, поэтому я и не смог пройти мимо такой вещи как 3d принтер. Купил себе принтер и заодно сделал и сайт с 3d моделями для онного. Выбрал я Altocms и в...

46 комментариев

+4
1. Есть простое правило — для получения общедоступных данных надо юзать GET. К сожалению, движку в наследство от прародителя досталось бездумное использование POST, где следовало бы обойтись GET, а где-то — GET там, где меняются данные, и нужен POST.

Поэтому, чтоб решить проблему системно, на уровне движка, нужно провести ревизию запросов и упорядочить использование GET/POST. Но на это пока не хватает времени.

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

2. Если это так, то да, баг, проверим, и, если подтвердится, то пофиксим
+1
Спасибо за ответы!

2. Мне стоит его на гихаб отписать?
0
Конечно! Это намного упростит поиск бага и его исправление разработчикам.
+1
Очень актуальная проблема, поддерживаю!

Пункт 2 можно решить если в /classes/actions/ActionRegistration.class.php поменять строчку
$this->User_Authorization($oUser, false);
на
$this->User_Authorization($oUser, true);

Но я столкнулся с другой проблемой при кэшировании через nginx, всем посетителям назначается один PHPSESSID (из кэша). Поэтому и при регистрации отображается одна и та же каптча
+2
Большое спасибо за подсказку. Проблема (2) действительно решилась.

А Вашу проблему я решил отключением модального окна для логина/регистрации и исключив страницу регистрации из кеширования nginx.
0
А Вашу проблему я решил отключением модального окна для логина/регистрации и исключив страницу регистрации из кеширования nginx.
Можно поподробнее пожалуйста насчет вот этого, что где поправить. Тоже собираюсь создавать сайт на alto и стоит связка apache+nginx.
+1
Та вроде все просто.
Если есть работающий nginx, то по Котерову делаете настройки.

Модальное окно отключается на уровне верстки. А запретить кеширование для конкретного урла просто по примерам того же Котерова.
0
Дайте пожалуйста ссылку где Котеров это описывает… или нужна его книжка по php? Я что то не врублюсь никак:) Легко сказать — по Котерову делайте:)
+1
Я дам конфиг для LiveStreet:


#by Genius_A ---------------------------------------------------------

    proxy_cache_path /usr/local/www/nginx-cache levels= keys_zone=wholepage:50m max_size=1G;
    proxy_cache_bypass $cookie_key;
    proxy_no_cache $cookie_key;

#--------------------------------------------------------------------------
	server {
		server_name sla.kiev.ua www.sla.kiev.ua;
		listen 91.218.212.236;
		disable_symlinks if_not_owner from=$root_path;
		set $root_path /usr/local/www/data/virtual/sla/data/www/sla.kiev.ua;

#by Genius_A
                gzip on;
                gzip_disable "MSIE [1-6]\.(?!.*SV1)";
                gzip_comp_level  2;
                gzip_min_length 1000;
                gzip_types text/css application/x-javascript text/javascript application/json;
		
		
		location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
			root $root_path;
                
			#access_log /usr/local/www/data/virtual/nginx-logs/sla isp;
			#access_log /usr/local/www/data/virtual/httpd-logs/sla.kiev.ua.access.log ;
                        access_log off;
                        expires 1y;
                        add_header Cache-Control private; 

			error_page 404 = @fallback;
		}
		
		location ~* ^/(engine|login|registration|ajax|settings|video|people)/ {	
			proxy_pass http://91.218.212.236:81;
			proxy_redirect http://91.218.212.236:81/ /;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;

			#try_files $uri @fallback;
			
		}

		location / {
#by Genius_A
                        proxy_cache wholepage;
                        proxy_cache_valid 200 301 302 50m;
                        proxy_cache_valid 404 50m;
			proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
#proxy_hide_header "Set-Cookie";
			proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
			
			
			proxy_pass http://91.218.212.236:81;
			proxy_redirect http://91.218.212.236:81/ /;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;
		}
		
		
		
		location ~* ^/(webstat|awstats|webmail|myadmin|pgadmin)/ {
			proxy_pass http://91.218.212.236:81;
			proxy_redirect http://91.218.212.236:81/ /;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;
		}
		location @fallback {
			proxy_pass http://91.218.212.236:81;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;
		}
+1
Закрывающей скобки не хватает
0
Хмм кстати, а у Вас какая версия nginx?
nginx -V
nginx version: nginx/0.8.54
TLS SNI support enabled
configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/build/buildd/nginx-0.8.54/debian/modules/nginx-upstream-fair


У меня, например, вот эта деректива не срабатывает disable_symlinks if_not_owner from=$root_path;
0
Все работает безупречно, с учетом правок в /classes/actions/ActionRegistration.class.php $this->User_Authorization($oUser, false); на $this->User_Authorization($oUser, true);

Но, получается так, что, когда пользователь логинится ему подставляется кэш страницы как будто он не залогинен, хотя по факту, если допустим для админа написать site.ru/admin админка сайта открывается. Правда это для LS, но думаю, что это не связано с CMS. Также если «погулять» по тем страницам, на которых другие пользователи не заходили, кэш страницы отдается уже с залогиненным пользователем.
0
Проверьте наличие куки по которой происходит проверка.
0
Я пытался понять, что откуда берется, часть понял, а часть нет(

proxy_cache_bypass $cookie_key;
proxy_no_cache $cookie_key;

Как я понимаю, это всегда такие значения для Livestreet.

pastebin.com/ySPvmt4X
Вот мой полный nginx.conf

При этом скачал плагин Firebug и там нет переменной key среди cookie, посмотрел в DOM, есть только LIVESTREET_SECURITY_KEY.
0
к сожалению не смог отредактировать, верная ссылка pastebin.com/yRDiyctL
0
т.к. сайта не вижу, то попробую предположить, что у вас логин и регистрация возможны по любому адресу. А нужно что бы это были отдельные УРЛы.
0
У нас с вами один и тот же шаблон Fortune.

логин по пути site.ru/login/
регистрация по пути site.ru/registration/

правда если на Вашем сайте кликнуть по «создать», войти или зарегистрироваться, то перенаправляет на отдельную страницу sla.kiev.ua/login/ или sla.kiev.ua/registration/, а у меня выскакивает окно на js, где на выбор «Войти», «Регистрация» или «Восстановление пароля».

сайт я Вам в личку скинул.
0
<code>
#--------------------------------------------------------------------------
	gzip on;
	gzip_disable "msie6";
	gzip_vary on;
	gzip_proxied any;
	gzip_comp_level 5;
	gzip_buffers 16 8k;
	gzip_http_version 1.1;
	gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    proxy_cache_path /var/lib/nginx/wholepage levels=1:2 keys_zone=wholepage:50m max_size=1G;
    proxy_cache_bypass $cookie_key;
    proxy_no_cache $cookie_key;

#--------------------------------------------------------------------------

</code>

<code>
        server {
                server_name site.ru www.site.ru;
                listen 11.111.111.250;
                set $root_path /var/www/path/data/www/site.ru;

		gzip_min_length 1000;

                location / {
#by Genius_A
                        proxy_cache wholepage;
                        proxy_cache_valid 200 301 302 50m;
                        proxy_cache_valid 404 50m;
                        proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
#proxy_hide_header "Set-Cookie";
 #                       proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
                        
                        
                        proxy_pass http://91.228.153.250:8080;
                        proxy_redirect http://91.228.153.250:8080/ /;
                        proxy_set_header Host $host;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header X-Real-IP $remote_addr;
 #                       proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
                }
	}

</code>

Если убирать proxy_ignore_headers «Cache-Control» «Expires» «Set-Cookie»; то все работает при логировании, и последующем выходе. Но, если использовать не только location / а и другие location как у Вас в примере, то кэш будет писаться в виде:
<code>
цpR
Ќ
KEY: GET|||site.ru|/templates/skin/fortune/images/favicon.ico?v1
HTTP/1.1 200 OK
Date: Wed, 30 Oct 2013 11:15:37 GMT
Server: Apache/2.2.17 (Ubuntu)
Last-Modified: Sun, 16 Dec 2012 14:56:32 GMT
ETag: "17c800f3-37e-4d0f978628810"
Accept-Ranges: bytes
Content-Length: 894
Connection: close
Content-Type: image/x-icon
</code>

При этом nginx.conf имеет такой вид:
<code>
#--------------------------------------------------------------------------
        server {
                server_name site.ru www.site.ru;
                listen 11.111.111.250;
                set $root_path /var/www/path/data/www/site.ru;

		gzip_min_length 1000;

		error_page 404 = @fallback;

		location ~* ^/(webstat/|awstats|webmail/|myadmin/|manimg/|pgadmin/) {
			proxy_pass http://111.111.111.250:8080;
			proxy_redirect http://site.ru:8080/ /;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Real-IP $remote_addr;
		}


                location / {
#by Genius_A
                        proxy_cache wholepage;
                        proxy_cache_valid 200 301 302 50m;
                        proxy_cache_valid 404 50m;
                        proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
#proxy_hide_header "Set-Cookie";
 #                       proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
                        
                        
                        proxy_pass http://11.111.111.250:8080;
                        proxy_redirect http://site.ru:8080/ /;
                        proxy_set_header Host $host;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header X-Real-IP $remote_addr;
 #                       proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
                }
		location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
			root /var/www/alser/data/www/site.ru;
			access_log /var/www/httpd-logs/site.ru.access.log ;
			access_log /var/www/nginx-logs/path isp;
		}
		location @fallback {
			proxy_pass http://11.111.111.250:8080;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Real-IP $remote_addr;
		}

	}
}
#--------------------------------------------------------------------------


</code>

При этом логирование и разлогирование работает, ну это видно и из кэша wholepage, что там мало данных.
Отредактирован:
0
Да… надо почитать про настройки Nginx, у меня например в конфиге Nginx вот этих строк вообще нет:
proxy_cache_path /usr/local/www/nginx-cache levels= keys_zone=wholepage:50m max_size=1G;
proxy_cache_bypass $cookie_key;
proxy_no_cache $cookie_key;
Папки по такому пути тоже нет никакой /usr/local/www/nginx-cache

Зато есть какие то:
proxy_buffers 8 32k;
proxy_buffer_size 64k;
+1
Папку создать надо. Собственно там кеш и лежит.
А эти строчки и есть ответственные за кеш.
0
Это кусок кода в файле nginx.conf, который относится к сайту на LS? Или эти 3 строки можно применить ко всем хостам на сервере? Прости если туплю:)
+1
Конкретно то, что Вы привели может относится ко всем сайтам.
Для каждого сайта все равно нужно прописывать:
proxy_cache wholepage;
                        proxy_cache_valid 200 301 302 50m;
                        proxy_cache_valid 404 50m;
                        proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
#proxy_hide_header "Set-Cookie";
                        proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
0
Спасибо огромное, заодно обновил весь сервер и nginx с 0.6.7 до 1.4.2, настроил по вашему, реально намного быстрее сайты летать стали. Теперь еще в каждый хост добавлю что вы прописали, плюсанул везде и в профиль. Большое человеческое спасибо!
Отредактирован:
0
Если не прописать все в комплексе, то работать оно вообще не будет. И работать быстрее оно будет только для не зарегистрированных.
0
Странно… теперь авторизация не работает… причем как на сайтах на LS так и не на LS. На LS окно авторизации висит с введенными данными и все, через autoopenid авторизуюсь, но после авторизации пишет Ошибка: 404. После перехода на главную — авторизация слетает, нет аватара админа и иконки входа в админпанель. С сайтами не на LS тоже непонятно, просто не происходит авторизация и все. Где я мог накосячить люди?
0
Значит почему-то авторизированным выдается из кеша ответ.
0
Один косяк нашел у себя, строку #proxy_hide_header «Set-Cookie»; я скопировал без #. Теперь не на LS все нормально. На LS почему то сразу залогинен админом… Наверное на всех сайтах на LS или alto нужно поменять в /classes/actions/ActionRegistration.class.php $this->User_Authorization($oUser, false);
на
$this->User_Authorization($oUser, true);
0
Хотя нет. Дело скорее в:
proxy_cache_bypass $cookie_key;
    proxy_no_cache $cookie_key;
0
Поменять это однозначно стоит.
А логиняться все админом, т.к. он сгенерил кеш.
Проверьте правильность этого:
location ~* ^/(engine|login|registration|ajax|settings|video|people)/ { 
                        proxy_pass http://91.218.212.236:81;
                        proxy_redirect http://91.218.212.236:81/ /;
                        proxy_set_header Host $host;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header X-Real-IP $remote_addr;

                        #try_files $uri @fallback;
                        
                }
0
На LS там $this->User_Authorization($oUser, false); в двух местах в 209 строке, где «Сразу авторизуем» и в 282 строке где «Сохраняем юзера»… везде поменять на true?
0
Я менял только в 209
0
Блин, теперь не разлогинивается на LS… Hacking attemp! пишет:)
0
А выложите Ваш конфиг
0
Все вернул обратно в 282 строке false — нормально заработало.
0
Такую конфигурацию желательно применять на сайтах только с LS или Alto… На других системах кое где проявились глюки, например отвалилась авторизация через соцсети (mod Eauth yii), на joomla в админке не показывает изменения… т.е. удалил я пользователя, в PMA вижу, что пользователя в базе нет, а в админке по прежнему есть… ну и еще несколько глюков было. Так что для LS и Alto норм., для других проверять и тестировать.
0
Конечно это только для ЛС. Мало того, это даже именно под мой сайт.
0
Пришлось на одном из сайтов в секции location / {
закомментировать вот это:

#    proxy_cache wholepage;
                   #    proxy_cache_valid 200 301 302 50m;
                   #    proxy_cache_valid 404 50m;
                   #   proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
                   #   proxy_hide_header "Set-Cookie";
                   #     proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";


Потому как полностью развалилась верстка сайта. Разваливалась при разлогинивании на сайте, если залогинивался то все нормально. Закоменнтировал и все стало нормально. Какие мысли ребята? Может я не туда кусок кода вставил… Просто раньше работало, потом вдруг такой обвал…
0
а) У меня сделано: /classes/actions/ActionRegistration.class.php поменять строчку
$this->User_Authorization($oUser, false);
на
$this->User_Authorization($oUser, true);
б) Бьюсь с тестовым сайтом, никак не получается настроить кэширование статики. Огромное благодарю Genius_A за выложенный код и за комментарии в личке. Убрал по его совету классы js-login-form-show и js-registration-form-show. При этом:
1) Попытался зарегистрироваться, и походить по сайту, и разлогиниться. Так все успешно работает. И только один раз на момент от регистрации до выхода в первый раз.
2) Потом попытался без входа под каким-либо пользователем походить по страницам:
«Топики», «Блоги», «Люди», «Активность», «About»
3) Потом попытался снова войти под этим же пользователем, и выйти. При этом после успешного входа, на страницах «Топики», «Блоги», «Активность», «About» видно, что как будто польльзотель не залогинен, а на страницах, где я не был, например топик «Ким Кардашиан и Канье Уэст показали свою любовь к Givenchy в эти выходные!» видно, что я залогинен под пользователем, в моем случае «test», также видно это же и на странице «Люди», так как у нас «location ~* ^/(engine|login|registration|ajax|settings|video|people)/».

Конфиг nginx.conf brouhaha.ru/nginx.conf_my
Сам сайт brouhaha.ru/

Что делать ума не приложу…

PS: Genius_A благодарю за помощь.
0
При чем сам кэш имеет такой вид: brouhaha.ru/cache.txt
0
Может вот это
gzip on;
                gzip_disable "MSIE [1-6]\.(?!.*SV1)";
                gzip_comp_level  2;
                gzip_min_length 1000;
                gzip_types text/css application/x-javascript text/javascript application/json;

не нужно в каждый хост запихивать а прописать для всего сервера?
Тоже бьюсь никак не могу нормально настроить Nginx… у меня еще усугубляется что на сервере разные сайты на разных системах… Но вот для LS никак не подберу оптимальный конфиг… то одно, то другое:(
0
На сайтах Altocms использовал эту проверку, но работает, тончее не работает аналогично Livestreet:
proxy_cache_bypass $cookie_user_key;
proxy_no_cache $cookie_user_key;
Отредактирован:
0
а у Вас какая версия nginx?
0
У меня 1.4.2
0
location / {
#by Genius_A
			error_page 418 = @fallback;
		        if ($cookie_key != "") {
                        return 418;
		        }
                        proxy_cache wholepage;                       
                        proxy_cache_valid 200 301 302 50m;
                        proxy_cache_valid 404 50m;
                        proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
#proxy_hide_header "Set-Cookie";
                        proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";  
                        
                          
                        proxy_pass http://11.228.153.250:8080;
			proxy_redirect http://11.228.153.250:8080/ /;
                        proxy_set_header Host $host;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header X-Real-IP $remote_addr;
                }


При этом кешируются все как и раньше. При проверке:

			error_page 418 = @fallback;
		        if ($cookie_key = "") {
                        return 418;
		        }

передается сразу на @fallback.

Хмм у меня последняя версия Livestreet 1.0.3 и в config.php нету параметра $config['security']['user_session_key']. Хотя после проставления этого параметра ошибка моя всё равно присуствует.
0
Блин теперь страницы в Trustlink не переиндексируются… их робот не видит код биржи. Никто не сталкивался с подобной проблемой ребята?
0
Ложная тревога, настройки Nginx ни при чем, проблема решена, кому интересно тут livestreet.ru/blog/questions/16259.html
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.