Cookies and Internet Explorer

Cookies for everybodyImagine you have a Zend Framework (version 1) application on a domain example.org, and another on a domain admin.example.org. They both have authentication mechanisms using Zend_Auth. This authentication information is stored in a browser cookie. Now I came across this problem that being logged in on both systems does not pose any problems with Google Chrome or Mozilla Firefox, but for some very strange reason, Microsoft Internet Explorer didn’t like it. The admin.example.org domain would be broken if you were logged in on example.org first. The server spewed out a 500 Internal Error, so I checked in the server logs to see what the heck was happening.

It turned out that the Account class, which I stored with the Zend_Auth instance in the cookie, could not be used in the admin side of the system. Of course, the public side is using a different application prefix than the admin side, so the class names in both systems are different, for a good reason. I’ll call the classes FE_Model_Account and BE_Model_Account, just to give you a visual. So what happened was the following:

  1. Log in on example.org
  2. A FE_Model_Account class instance was stored with Zend_Auth in the cookie
  3. Go to admin.example.org, which in Internet Explorer, happened to read that cookie, and load the FE_Model_Account class
  4. This class, of course, does not exist in the admin side, so it barfed, giving us a 500 Internal Error

Seven hells!

What surprised me most was, why in the seven hells would Internet Explorer use the public site’s cookie for the admin site?! This is a question that will remain unanswered in this blog, because I refuse to go through all the evil abominations in this ugly piece of shit called Internet Explorer. But I will give you the solution to deal with this problem.

If the cookie domain is set properly, Internet Explorer will use it. So here is how to set it properly in a Zend Framework application. First, have the following line in your application.ini files. For the public site, this will be:

resources.session.cookie_domain = "example.org"

And for the admin site:

resources.session.cookie_domain = "admin.example.org"

You also need to bootstrap the session resource as early as possible so that it is set correctly at the beginning. So in your Bootstrap.php file, have this in your first init function:

$this->bootstrap('session');

Now, Internet Explorer will stay away from the example.org cookie when accessing admin.example.org, like it bloody well should by default. Which brings me to the following question: should we default the cookie_domain setting to the application’s domain name in Zend/Session.php?

What are your thoughts?