Symfony Session Timeout Annoyance…
I have recently found that symfony doesn’t attempt to properly maintain the user’s session after logout.
This is a tad annoying as any attributes that have been set during a valid login session will still be set when the user is communicating with the server. It is also a security risk.
Symfony provides the basic building blocks for creating an application, and session management is a part of that. The myUser class contains paramter, attribute, credentials classes as well as some variables like culture (for internationalisation), authenticated and timedout.
The ‘authenticated’ variable’s use should be pretty obvious - when the application is processing the users login it should set the authenticated variable to ‘true’ :
$this->getUser()->setAuthenticated(true);
The ‘timedout’ variable is set automatically be symfony when … alas … the users session has expired/timed out - pretty self explanatory.
The problem comes when your application sets any parameters or attributes during the sessions lifetime. For example, in my application when the user logs in I set a session variable ‘nickname’ so that I can reference/identify the user during any subsequent requests :
$this->getUser()->setAttribute('nickname', $user->getNickname());
This is pretty basic and normal functionality.
This attribute should die along with the session, when it times out - but it doesn’t. There are some perfectly valid reasons why this happens e.g The ‘Validated User’ and the ‘Browsing User’ are two different things to the system but the contents of the shopping cart are not. Another example would be website tracking software. It monitors where users are and what they are looking at - a very good tool for marketing. This type of software doesn’t have to care whether the user is logged in order not as its only concern is where they are and what they are doing. This information needs session data to follow the user. If all session data were cleared after the user logged out - then the monitoring software would be thinking a new user arrived - which would be wrong.
What is needed in this situation is a trigger or a test that determines if the session has expired and if it has - then action something appropriately.
The only way that I have determined to do this is by editing the myUser.class.php file for the application (and every other application) in your project.
As the myUser class is instantiated before any actions we can alter/clean up the session before any proper processing is done :
class myUser extends sfBasicSecurityUser
{
public function initialize($context, $parameters = array()) {
parent::initialize($context, $parameters = array());
if($this->isTimedOut()) {
$this->getAttributeHolder()->remove('nickname');
}
}
}
If you don’t like the idea of having to do this for all your applications - then you can create a new class and make the myUser class extend it instead (you must ensure that the new class also extends sfBasicSecurityUser. That way you have one central place to update when you need to clean up your session.
Hope this helps…
If you have any better ways of doing this - please let me know. I’d be interested to hear your take on it.