Welcome! Log In Create A New Profile

Advanced

Кеширование в зависимости от куки

Posted by wastemaster 
Кеширование в зависимости от куки
April 05, 2010 03:47AM
Тема является логическим продолжением проблемы описанной тут - http://forum.nginx.org/read.php?2,3173,5612

Стоит цель: неавторизованным пользователям показываем кешированный ответ factcgi, авторизованным - незакешированный.

Софт: nginx/0.8.34 + spawn-fcgi + php

Сделал все согласно рекомендациям

1. Добавил $cookie_login_id в factcgi_cache_key
2. В бекенде сделал отдачу заголовка "X-Accel-Expires: 0" если пользователь авторизован

локейшн вот такой:

[code]
location ~ \.php$ {

fastcgi_pass 127.0.0.1:1026;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 8 128k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/www/server-root/data$fastcgi_script_name;
include fastcgi_params;

fastcgi_cache wholepage;
fastcgi_cache_valid 200 301 302 304 1m;
fastcgi_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri|$cookie_l
fastcgi_hide_header "Set-Cookie";
fastcgi_ignore_headers "Cache-Control" "Expires";
}
[/code]

Все работает но!

Если ставить
[code]
fastcgi_pass_header Set-Cookie;
[/code]

То я могу ставить куки, но при этом в кеш попадает сессионная кука PHPSESSID
и при отдаче страницы из кеша - народ автоматом залогинивается под чужим аккаунтом (от того с чьей кукой закешировался) если на этой куке открыта сессия

Если запрещать передачу куков:
[code]
fastcgi_hide_header Set-Cookie;
[/code]

То соответственно не могу залогиниться, потому что кука не ставится

Как нужно конфигурировать nginx в этом случае?
На ум приходит только вариант с проставлением куки с другого виртхоста (в котором куки разрешены)
Или если бы nginx при отдаче ответа из кеша не передавал куки вообще



Edited 1 time(s). Last edit at 04/05/2010 03:48AM by wastemaster.
Re: Кеширование в зависимости от куки
April 05, 2010 10:28PM
Решение нашлось опытным путем. Подумалось, что нужно куда то вынести функционал по проставлению и удалению кук, а на остальных урлах куки запретить. Те схема примерно следующая:

1. В бекенде при запросах от авторизованных пользователей выставляется заголовок "X-Accel-Expires: 0" - при этом ответ от fastcgi не будет положен в кеш.
2. Добавлена $cookie_login_id в factcgi_cache_key
3. Выставлена fastcgi_hide_header Set-Cookie; Чтобы при отдаче кешированной странице не отдавать людям чужие куки.
4. Локейшны для входа и выхода (login/logout) вынесены отдельно, с тем чтобы они работали без кеширования и могли ставить и удалять куки. При логине соответсвенно необходимо поставить пользователю куку login_id с его ID в системе, а при выходе эту куку удалить.

[code]
# Nginx factcgi cache config for anonymous users (with no cookie login_id)
# Fastcgi responce for logged user will not be cached

http {

# Экзотичный лог-формат, чтобы достоверно посмотреть с какими значениями будет строиться cache_key
log_format cache_main '$remote_addr $request '
'"$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri|$cookie_login_id"';


fastcgi_cache_path /some/dir/nginx-cache levels= keys_zone=wholepage:500m;

server {
listen 77.106.108.204:80 default rcvbuf=8k;
server_name mydomain.ru www.mydomain.ru *.mydomain.ru;
client_max_body_size 220m;
charset utf-8;

access_log /var/log/http/mydomain.ru_access.log cache_main;

root /usr/local/www/mydomain.ru/data;
index index.php index.html index.htm;

error_page 404 /50x.html;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/mydomain.ru/data;
}

location / {
try_files $uri $uri/ @mybackend;
}

location ~ \.svn {
deny all;
}

# В этом лекейшне можно ставить и удалять куки - кеширования здесь нет
# In backend those location are able to set and delete cookies (no caching)
location ~ ^/user/(login|logout|new) {
fastcgi_pass 127.0.0.1:1026;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/www/mydomain.ru/data/index.php;
include fastcgi_params2;
}

# Этот локейшн нужен для админки проекта (простая http авторизация)
# Admin side - cache disabled + simple http auth
location ~ ^/admin-side/ {
auth_basic "Adminko";
auth_basic_user_file /usr/local/www/mydomain.ru/.passwd;
fastcgi_pass 127.0.0.1:1026;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/www/mydomain.ru/data$fastcgi_script_name;
include fastcgi_params;
}

# Сюда приходит запрос "GET /" и запросы на отдельнолежащие php файлы
# Кеширование включено, куки запрещены
# Location for separate php-files and GET / request
# cache enabled + SetCookie is hidden
location ~ \.php$ {
try_files $uri @mybackend;
fastcgi_pass 127.0.0.1:1026;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/www/mydomain.ru/data$fastcgi_script_name;
include fastcgi_params;

fastcgi_cache wholepage;
fastcgi_cache_valid 200 301 302 304 5m;
fastcgi_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri|$cookie_login_id";
fastcgi_hide_header "Set-Cookie";
fastcgi_ignore_headers "Cache-Control" "Expires";
}

# Все остальные динамические урлы
# кеширование включено
# rest dynamic urls - cache enabled
location @mybackend {
fastcgi_pass 127.0.0.1:1026;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 8 128k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/www/mydomain.ru/data/index.php;
include fastcgi_params2;

fastcgi_cache wholepage;
fastcgi_cache_valid 200 301 302 304 5m;
fastcgi_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri|$cookie_login_id";
fastcgi_hide_header "Set-Cookie";
fastcgi_ignore_headers "Cache-Control" "Expires";

}

}
[/code]

содержимое файлика fastcgi_params
[code]
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

[b]fastcgi_param SCRIPT_NAME $fastcgi_script_name;[/b]

fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
[/code]

содержимое файлика fastcgi_params2
[code]
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

[b]fastcgi_param SCRIPT_NAME /index.php;[/b]

fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
[/code]

http://tomsk.fm
Re: Кеширование в зависимости от куки
November 18, 2010 05:16AM
[quote="1. В бекенде при запросах от авторизованных пользователей выставляется заголовок \"X-Accel-Expires: 0\" - при этом ответ от fastcgi не будет положен в кеш."]
Не понимаю.
На сколько мне известно, \"X-Accel-Expires: 0\ используется в модуле mod_accel, который предназначен для использования Apache в режиме акселератора. Т.е., как я понимаю, NGINX, получив ответ от бэкенда и прежде, чем отдать его клиенту проверяет наличие этого заголовка и установленное в нём значение, а затем принимает решение о том, положить в кэш этот ответ или нет.
А как тогда это работает без Апача, когда бэкенд не Апач, а FastCGI-сервер?
Где это конкретно в бэкенде (который не Апач, а FastCGI) выставлять заголовок \"X-Accel-Expires: 0\ и как проверять в нём (бэкенде, который не Апач, а FastCGI) авторизован пользователь, или нет?
[/quote]
[quote="Выставлена fastcgi_hide_header Set-Cookie; Чтобы при отдаче кешированной странице не отдавать людям чужие куки."]
И второй вытекающий вопрос: а какой смысл скрывать в заголовке ответа клиенту куки, если из-за установленной директивы \"X-Accel-Expires: 0\ все ответы для авторизованных пользователей вместе с их куками и так в кеш не попадают?
[/quote]
Re: Кеширование в зависимости от куки
November 18, 2010 10:19AM
roga_i_kopita Wrote:
-------------------------------------------------------
> > Не понимаю.
> На сколько мне известно,
> \"X-Accel-Expires: 0\ используется в
> модуле mod_accel, который
> предназначен для
> использования Apache в режиме
> акселератора. Т.е., как я
> понимаю, NGINX, получив ответ
> от бэкенда и прежде, чем
> отдать его клиенту
> проверяет наличие этого
> заголовка и установленное
> в нём значение, а затем
> принимает решение о том,
> положить в кэш этот ответ
> или нет.
> А как тогда это работает
> без Апача, когда бэкенд не
> Апач, а FastCGI-сервер?
> Где это конкретно в бэкенде
> (который не Апач, а FastCGI)
> выставлять заголовок
> \"X-Accel-Expires: 0\ и как проверять
> в нём (бэкенде, который не
> Апач, а FastCGI) авторизован
> пользователь, или нет?
>
>
> И второй вытекающий вопрос:
> а какой смысл скрывать в
> заголовке ответа клиенту
> куки, если из-за
> установленной директивы
> \"X-Accel-Expires: 0\ все ответы для
> авторизованных
> пользователей вместе с их
> куками и так в кеш не
> попадают?
>

под бэкэндом я имел ввиду - пхп приложение - заголовок X-Accel-Expires: 0 выдается из всех пхп скриптов которые смотрят авторизованные пользователи - те этот материал в кеш не попадает. Остальное все автоматически кешируется.

по поводу второго вопроса - чото я сам задумался.... чего я там намудрил, но тем не менее в таком виде всё работает.
Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 187
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready