Unexpected expiration of Zend_Auth sessions

Coding
By Jasper | September 30, 2010

I was struggling a bit with managing PHP sessions within the Zend Framework. More specifically, the session of an authenticated user expired after 24 minutes (1440 seconds), even though I instructed Zend to set the expiration to 86400 seconds (1 day), like this:

$db = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($db);

$authAdapter->setTableName('users');
$authAdapter->setIdentityColumn('username');
$authAdapter->setCredentialColumn('password');

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);

// Did the user provide the correct credentials?
if ($result->isValid()) {

	// Store all userdata except the password in the session
	$data = $authAdapter->getResultRowObject(null,'password');
	$auth->getStorage()->write($data);

	$authSession = new Zend_Session_Namespace('Zend_Auth');
	$authSession->setExpirationSeconds(86400);

}

How sessions work and what you should be aware of

PHP stores the session ID in a cookie and, when a new request arrives, uses the session ID from the cookie to retrieve the session file from disk. If a session expires, this can have at least two causes 1) its session file on the server is gone or 2) the related cookie is no longer available. As PHP stores its sessions in a shared location (usually /tmp/), I figured someone or something else was tampering with my session files.

After having some deep thoughts, I came to the following conclusion. In a shared hosting environment, other PHP scripts are also putting their session files in /tmp/. This should not be a problem, however, garbage collection takes place on system wide intervals (which default to 1440 seconds) and (worse!) scripts from other users can even decide to override this interval (if you’re really trigger happy you can delete all session files, every minute). In summary: my sessions are not safe in /tmp/!

Saving your session files in a different location

Fortunately, Zend Framework (beyond version 1.8) offers a nice solution to store your session files in a different location. First you have to create a folder and chmod it to 777 so it’s writable for PHP. In this example I created the folder in “/application/../data/session/”. Next, you tell your application to change the save path of the sessions and the lifetime of your sessions by adding the following lines to your application.ini (86400 seconds = 24 hours):


resources.session.save_path = APPLICATION_PATH "/../data/session/"
resources.session.gc_maxlifetime = 86400
resources.session.remember_me_seconds = 86400

Finally, to make this work, you need to bootstrap “session”, by putting the following code in your Bootstrap.php:


protected function _initSessions() {
 	$this->bootstrap('session');
}

To check if this worked, monitor the new sessions folder and, as soon as you log in, a new session file will appear. Deleting this file will log you out.

9 comments on “Unexpected expiration of Zend_Auth sessions”

  1. Excellent post. I have been working on an internal application for about 18months and could not understand why users where being periodically logged out. Used your example above and it has fixed the problem.

    You’re a live saver, thanks very much.

  2. You’re welcome! I totally understand where you’re coming from. Glad to help out. :-)

  3. Thank You!. This is an excellent post.

  4. @Mourad: Thanks for your kind words. :-)

  5. Thank you! Looks like it worked for me :)

  6. Can’t be a trouble placing session files in another directory? They will inflate the disk, when will they be deleted ?

  7. Excellent article but just a quick note-you’ve got the number of seconds in a day wrong by a factor of 10! There are 86400 seconds in a day and you’ve written 864000, which is actually 10 days…

  8. @Jeremy: You’re absolutely right (of course)! Thanks for correcting this!

  9. Bedankt! Hope this works, just implemented it, and will have to wait and see if the users still complain…

Your comment