Using nginx, how to conditionally hide multiple set-cookie response headers coming from backend?
<p>I have an nginx config using <code>fastcgi_pass</code>. I'm sure it would work the same with <code>proxy_pass</code>.</p>

<p>For anonymous/guest users, I wish to hide the <code>set-cookie</code> response header set by php's <code>session_start()</code> (I also hide the <code>cache-control</code>, <code>expires</code> and <code>pragma</code> headers), but for logged-in users (and when an anonymous user is logging in), I wish to pass all the <code>set-cookie</code> headers sent by the backend.</p>

<p>I made the app set a special header (<code>X-SPECIAL</code>) I can inspect in nginx to decide which kind of response it is - for guests or not.</p>

<p>When the backend sends a single <code>set-cookie</code> header, I successfully pass it only when needed using <code>$upstream_http_set_cookie</code>. But when the backend sets multiple cookies using multiple <code>set-cookie</code> response headers, <code>$upstream_http_set_cookie</code> contains only one value, so the client only sees one cookie. This results in login not working.</p>

<p>How to get all values in <code>$upstream_http_set_cookie</code>?
Or alternatively, how to conditionally set <code>fastcgi_hide_headers</code>? I know that <code>hide_headers</code> does not support variables, and it seems it cannot be set differently per-request.</p>

<p>Do I have to use openresty and lua?</p>

<p>My config:</p>

<pre><code>fastcgi_cache_path /var/nginx/cache levels=1:2 keys_zone=my_cache:10m;

map $upstream_http_x_special $not_store_in_cache {
  default "1";
  guest "0";
}

map $upstream_http_x_special $maybe_set_cookie {
  default $upstream_http_set_cookie;
  guest "";
}

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.php index.html index.htm;

    server_name localhost;

    location / {
        try_files $uri $uri/ =404;
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;

        set $not_from_cache "";
        if ($request_method !~ ^(GET|HEAD)$) {
            set $not_from_cache "1";
        }
        if ($cookie_phpsessid != '') {
            set $not_from_cache "1";
        }
        # conditionally don't serve request from cache
        fastcgi_cache_bypass $not_from_cache;
        # conditionally don't store response into cache
        fastcgi_no_cache $not_from_cache$not_store_in_cache;
        fastcgi_cache my_cache;
        fastcgi_cache_key $scheme$host$request_uri;
        fastcgi_cache_valid any 1s;
        # serve from cache while generating next response
        fastcgi_cache_use_stale error timeout updating http_500 http_503;
        # single request to backend, no matter how many requests for same resource.
        fastcgi_cache_lock on;
        # store in cache regardless of response headers
        fastcgi_ignore_headers expires cache-control set-cookie;
        # remove these headers from response before passing back to client.
        fastcgi_hide_header pragma;
        fastcgi_hide_header expires;
        fastcgi_hide_header cache-control;
        fastcgi_hide_header x-special;

        # Fake conditional hide response header by always hiding and
        # conditionally adding it back.
        # Works only when there is a single "set-cookie" header,
        # fails when backend sets multiple cookies.
        fastcgi_hide_header set-cookie;
        add_header Set-Cookie $maybe_set_cookie;

        # standard code for php backend
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
</code></pre>