I will again talk about cookies, but this time, with a pinch of Zend_Auth.
Previously, I introduced a class to manage secure cookies. Now, we will see how to use it in a very common case : authentication with Zend_Auth.
Let us remind the main lines of Zend_Auth :
- Several authentication method are available (Database, digest file, LDAP directory, OpenID provider etc.). The method if defined by an "Adapter" : a class implementing Zend_Auth_Adapter_Interface
- Once authenticated, we must store the user's identity. By default, identity is stored in session, but any class implementing Zend_Auth_Storage_Interface can store the identity with its own method. That's what we will do here !
If you're like me and you don't like to use sessions, you may think that using sessions only to store users identities (a simple integer or a short string in most common cases) is a waste. Sessions are heavy and hard to manage when application run in a webserver farm.
What do you think about storing user identity on the client side ? You may think it's dangerous... and you're right ! We can already think about worst disastrous stories :
Generally, public don't like this kind of stories (especially your users). So we will use some cryptographic tricks to prevent malicious users from faking their identities. We will store the identity in a secure cookie (using BigOrNot_CookieManager class).
I wrote a class (implementing Zend_Auth_Storage_Interface) to store users identities in a secure cookie.
Here is how to use it :
$cookieManager = new BigOrNot_CookieManager('SECRET_KEY'); $authStorage = new BigOrNot_Auth_Storage_Cookie($cookieManager); $auth = Zend_Auth::getInstance(); $auth->setStorage($authStorage); [...]
By defaut, the cookie's name is "auth" and default parameters are passed to setcookie().
If you want to modify these parameters, you can pass a second parameter to BigOrNot_Auth_Storage_Cookie's constructor : an array (or a Zend_Config instance).
Supported options are : cookieName, cookieExpire, cookiePath, cookieDomain, cookieSecure, cookieHttpOnly. (Names are self explanatory, see setcookie()'s documentation if you have a doubt).
$cookieManager = new BigOrNot_CookieManager('SECRET_KEY'); $storageConfig = array( 'cookieName' => 'BigOrNauth', 'cookieExpire' => (time() + 3600), 'cookiePath' => '/', 'cookieDomain' => 'bigornot-fr.blogspot.com' ); $authStorage = new BigOrNot_Auth_Storage_Cookie($cookieManager, $storageConfig); $auth = Zend_Auth::getInstance(); $auth->setStorage($authStorage);
Identity is stored "serialized" so you can store every serializable data you want. Avoid big objects ! Big objects = big cookies. Don't forget that they're transmitted with all request.
Identity is stored encrypted, so you will not give any sensitive information using this technique
As we saw in the previous post, BigOrNot_CookieManager::setcookie() method need a "username" parameter (or any unique user identifier)
In BigOrNot_Auth_Storage_Cookie's case, i use a md5 hash of the serialized identity.