You can store PHP sessions in memcached and then access those session values in nginx to route traffic accordingly.  My use case was a WebRTC server (janus-gateway) that I wanted to be hidden behind a PHP authentication barrier.

First PHP must be set to store sessions in memcached.  Instructions can be found here.  I found the memcached extension had a bit more options than the memcache extension (notice the ‘d’ at the end of one), such as setting the memcached key prefix.

Once sessions are stored in memcached, you can now access them with nginx.  nginx already has support for accessing memcached, but I needed the eval block to evaluate the contents first so I could use the php session parser on it.

Adding these two modules requries recompiling nginx from source.  I downloaded the 1.8.1 source from http://nginx.org/en/download.html.  And I cloned the two repos for the modules I wanted: https://github.com/replay/ngx_http_php_session and https://github.com/vkholodkov/nginx-eval-module

I ran the nginx configure script with the paths to the two modules I wanted added in:

./configure --add-module=../nginx-modules/nginx-eval-module/ --add-module=../nginx-modules/ngx_http_php_session/ --with-http_ssl_module  --with-http_spdy_module --with-http_auth_request_module --with-http_stub_status_module

And recompiled and installed nginx.

And then in my virtual host nginx configuration I was able to add this to protect the path /janus:

    location ^~ /janus {
        eval $session {
            if ( $http_cookie ~* "PHPSESSID=([^;]+)(?:;|$)") {
                set $cookie_phpsessionid $1;
            }
            set $memcached_key "memc.sess.key.${cookie_phpsessionid}";
            memcached_pass 127.0.0.1:11211;
        }
        php_session_parse $result $session "loggedin";
        if ( $result != "b:1" ) {
            return 401;
        }

        proxy_pass https://localhost:8089/janus;
    }

This snippet of code grabs the session key out of the HTTP headers and then generates the memcached key from that and evaluates that into the variable $session.  We then pass that to the php parser to grab the contents of the loggedin element.  I could have parsed this further using the php_session_parse to get the bare value without the serializing identifier, but for this case it was easy enough to compare this way.

ngx_http_php_session – nginx module to parse php sessions

Source: replay/ngx_http_php_session: nginx module to parse php sessions

nginx-eval-module – A module for evaluating memcached or proxy response into variable

Source: vkholodkov/nginx-eval-module: A module for evaluating memcached or proxy response into variable

Categories: Memcached, nginx, PHP, Programming, Web

Leave a Reply