Nginx cache cookies issue

cachefastcginginx

I've configure nginx|php-fpm with nginx cache.

The problem i'm having is with the cookies and cache, i configure to bypass cookie name and some request_uri and working fine bypass it cool here.

Problem comes when passed few minutes if is signup or not my logged with different user and when change in different pages i'm logged with diffent user or same user.

When i see the header i see perfect fine is bypass by cookies if logged and when is not logged say hit, pages i setup as bypass says bypass but logged as an user (not logged)

Not sure what happen here i try everything and i can't find the reason for this issue.

nginx.conf

fastcgi_cache_path /var/cache/nginx/dor levels=1:2 keys_zone=dor:10m inactive=60m max_size=1024m use_temp_path=off;

vhost.conf

    set $skip_cache 0;
    if ($request_method = POST) {
        set $skip_cache 1;
    }

    if ($query_string != "") {
        set $skip_cache 1;
    }

    if ($request_uri ~* "confirm|feed|login|lost|logout|signup|admin|user|index.php|sitemap.php") {
        set $skip_cache 1;
    }

    if ($http_cookie ~* "mainsite") {
        set $skip_cache 1;
    }

    add_header Fastcgi-Cache $upstream_cache_status;

    location ~ [^/]\.php(/|$) {

        try_files $uri =404;

        fastcgi_pass                    127.0.0.1:9002;
        fastcgi_index                   index.php;
        fastcgi_split_path_info         ^(.+\.php)(/.+)$;
        fastcgi_param                   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors        off;
        fastcgi_buffer_size             128k;
        fastcgi_buffers                 256 16k;
        fastcgi_busy_buffers_size       256k;
        fastcgi_temp_file_write_size    256k;
        fastcgi_cache                   dor;
        fastcgi_cache_valid             200 301 5m;
        fastcgi_cache_min_uses          3;
        fastcgi_cache_lock              on;
        fastcgi_cache_bypass            $skip_cache;
        fastcgi_cache_key               "$scheme$request_method$host$request_uri";
        fastcgi_cache_use_stale         error timeout updating invalid_header http_403 http_500 http_503;
        fastcgi_cache_revalidate        on;
        fastcgi_ignore_headers          Cache-Control Expires Set-Cookie;
        fastcgi_no_cache                $skip_cache;
        include                         /etc/nginx/fastcgi_params;
    }

Best Answer

The following is quite dangerous:

fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

With the Set-Cookie in the values, you're effectively allowing to cache someone's login request. You need to either hide it from response via fastcgi_hide_header (which would break login feature, if not done correctly) or use fastcgi_ignore_headers Cache-Control Expires; (which would break caching altogether, if you have a "bad" app, see below).

It is best to identify your "login location" (e.g. POST /login) and essentially create 2 cache configurations:

  1. Login location. Neither fastcgi_ignore_headers nor fastcgi_hide_header are required. Do not include them.

  2. Other pages location. This is required if your app unnecessarily starts session (sends Set-Cookie) for any page; quite many do.

    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
    fastcgi_hide_header Set-Cookie;
    

... and just as a bonus. NGINX is all great, but Varnish is quite flexible about manipulating both sets of client and upstream headers, e.g.:

sub vcl_recv {
    if (req.http.cookie !~ "mainsite") {
        unset req.http.cookie;
    }
}
sub vcl_backend_response {
    if (beresp.http.Set-Cookie && bereq.url != "/login") {
        unset beresp.http.set-cookie;
    }
}