Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NGinx : How to test if a cookie is set or not without using 'if'?

Tags:

nginx

I am using the following configuration for NGinx currently to test my app :

location / {
            # see if the 'id' cookie is set, if yes, pass to that server.           
            if ($cookie_id){
                proxy_pass http://${cookie_id}/$request_uri;                
                break;
            }

            # if the cookie isn't set, then send him to somewhere else
            proxy_pass http://localhost:99/index.php/setUserCookie;
        }

But they say "IFisEvil". Can anyone show me a way how to do the same job without using "if"?
And also, is my usage of "if" is buggy?

like image 607
Shrinath Avatar asked Jul 18 '11 10:07

Shrinath


People also ask

How do I view cookies in nginx?

nginx allows you to extremely easily extract the value of a cookie. Simply use $cookie_<name> meta variable in whatever context you need. In this configuration snippet we pass the request to the upstream named “upstream” and extend it with a header “X-Session-id” set to the value if the cookie named “sid”.

Does nginx pass cookies?

NGINX is configured as a reverse proxy to an "Random Emoji App". On first access, the app will produce an emoji, and send cookies for session state. Repeat visits will show the same cookie. By default, all requests will send cookies directly to the client, in the normal manner.


1 Answers

There are two reasons why 'if is evil' as far as nginx is concerned. One is that many howtos found on the internet will directly translate htaccess rewrite rules into a series of ifs, when separate servers or locations would be a better choice. Secondly, nginx's if statement doesn't behave the way most people expect it to. It acts more like a nested location, and some settings don't inherit as you would expect. Its behavior is explained here.

That said, checking things like cookies must be done with ifs. Just be sure you read and understand how ifs work (especially regarding directive inheritance) and you should be ok.

You may want to rethink blindly proxying to whatever host is set in the cookie. Perhaps combine the cookie with a map to limit the backends.

EDIT: If you use names instead of ip addresses in the id cookie, you'll also need a resolver defined so nginx can look up the address of the backend. Also, your default proxy_pass will append the request onto the end of the setUserCookie. If you want to proxy to exactly that url, you replace that default proxy_pass with:

rewrite ^ /index.php/setUserCookie break;
proxy_pass http://localhost:99;
like image 86
kolbyjack Avatar answered Oct 05 '22 10:10

kolbyjack