af83

Encrypted Session Cookies in PHP

This must be PHP week on AF83's github, with a bunch of stuff that we hope can help someone out there. I will post about toupti and the others later, but first:

François (francois2metz) just released session-cookie that does just that. It puts your session data in the cookie.

Usually when you are doing PHP your session data is somewhere in a local store (either on the disk as a default, in your database or in some kind of DHT like memecache).

PHP lets you set quite easily the session handler for any of these methods (look at http://www.php.net/manual/en/function.session-set-save-handler.php).

Now this does pose some serious issues in terms of scalability. If you use a database or the file system this can be very hard on your disks. Opening a session is expensive, and distributing it over a large number of servers is hard complicated and may require more code then you imagined.

Sometimes all you want to have from the session is the user_id, yet when you get the session cookie you still have to pay a round trip to the database just to get it from there.

So.. one simple, cool solution, is just to send this data to the client as a cookie. Now you don't really want the user to be able to change the data (for example changing the user id and logging-in as a super duper admin). But this is not hard.. just encrypt it with your own secret, and the user will not be able either to modify or look at it.

Basic Usage

// just include session class
require_once 'session.php';
require_once 'Crypt/Blowfish.php'; // pear package, only needed when using SessionInCookie_DefaultCipher

SessionInCookie::setCipher(new SessionInCookie_DefaultCipher('mysecretkey'));

// start session normally
start_session();

// Read and write in session
$_SESSION['foo'] = 'bar';

// juste before output, call session_write_close
session_write_close();

// WARNING: now session data have been send to the client via encrypted cookie. You *CANNOT* write on $_SESSION.

echo 'Hello Word';

Advanced Usage

Custom cipher

class MyCipher implements SessionInCookie_Cipher
{
    public function encrypt($data)
    {
        return $data;
    }

    public function decrypt($data)
    {
        return $data;
    }
}

SessionInCookie::setCipher(new MyCipher());

Debug

You can use SessionInCookie_DummyCipher.

SessionInCookie::setCipher(new SessionInCookie_DummyCipher());

I do not think this solution is great when you have too much data in the session.. but that anyway is probably a very bad idea. If the data is important … please remember : sessions die.

get the code at: http://github.com/AF83/session-cookie

Enjoy

(btw some frameworks, written by serious people take this approach as a default…)

blog comments powered by Disqus