Your Session Has Timed Out

save failed posts for reuse after forced logout or autologin

I wish more developers would test their web applications for session timeout issues. Despite all rumors to the contrary, your users will not be dedicating their entire lives to using your web application in a punctual and timely manner. They have phone calls to take, meetings to go to, other websites and applications to attend to.

Is it really fair to kick users all the way out of your web application, or worse, blindly reject data they've submitted — just because they were impudent enough to wait a few hours since their last supplication to the web server gods? In most web apps, the penance is awfully severe for such a common sin.

Your Session Has Timed Out – Coding Horror


  1. Session duration problem

1. Settings for Session


There are a few key ini settings:

session.gc_maxlifetime -This setting (in seconds) tells the PHP garbage collector how long to keep the session valid. The default is 24 minutes.

session.gc_probability – The probability that the garbage collector will run and clean up old session data. The default value is 2.

session.cookie_lifetime – How long to keep the cookie written to the client machine valid. Defaults to 0, which means the cookie will expire at the end of the broswer session (at logout or when closing the broswer).


session.save_path – The path for session values to be saved. The default is /tmp, however it is important to change this to a custom folder for the application – especially if you are in a shared hosting enviorment. The garbage collector does not discriminate, and it will delete ANY session data that is older than the set limit, not just ones that correspond to your application.


1.1. Custom timeout

* FACTOR (8*60*60)


public $cf_nonce_lifetime	= 7200*FACTOR;
public $cf_gc_maxlifetime	= 1440*FACTOR;
public $cf_max_idle		= 1440*FACTOR;
public $cf_max_session		= 7200*FACTOR;	// time to unconditionally destroy active session

public $cf_regen_time		= 500;		// seconds between forced id regen
public $cf_cache_expire		= 180*60;	// ttl for cached session pages in seconds

Setting the above configuration well make sure your session will expire in X hours, and the garbage collector will run everytime session_start is called to cleanup expired sessions.

TODO: need config'ing -> constants.php?

1.2. Custom Session Storage

2. Dealing with POST data and expired sessions

2.1. AJAX

  • provide the user with the ability to re-login if the session has timed out prior to submitting a POST request.

2.2. JS

  • Create a background JavaScript process in the browser that sends regular heartbeats to the server. Regenerate a new cookie with timed expiration, say, every 5 or 10 minutes.
  • Create a warning message show timer with a warning message: "You've been logged off due to long inactivity. Save your form edits to text file. Log in again and re-submit."

That message could be called by function like:

setTimeout("session_expiry_warning()", session_duration); // here session_duration is a variable of session duration in milliseconds

The whole messaging system could look like this:

var session_duration=600000;

function reset_timer(){
	setTimeout("session_expiry_warning()", session_duration);

function session_expiry_warning(){
	alert("You've been logged off due to long inactivity.\nSave your form edits to text file to prevent loss.\nLog in again and re-submit.");

and this could be also connected with pressing Submit button with:

if (element.addEventListener) {
    element.addEventListener("submit", function(evt) {
    }, true);
else {
    element.attachEvent('onsubmit', function(evt){

2.3. Session

  1. make sure all your forms post to them-selfs (302 to them-selfs on success, so you don't have the "refresh" confirmation popup)
  2. In case you have an "if (is not logged in) { redirect to login page; }" block in more than one place, put that in a function and call that function everywhere.
  3. In that function, before the actual redirect, check 2 things:
    1. If the request was GET, and if so, store the URL in a session variable (redirect to it after login)
    2. If the request was a POST, store the #1 the URL and #2 the posted data in the session. Redirect to that #1 URL after the login, and use the #2 data to pre-populate the form fields on the page.

(Make sure to tie the data to the logged in user id or something)

So, from the user's point of view:

  1. login
  2. go to edit profile
  3. fill in profile
  4. go to a meeting for 45 min (session is 24)
  5. come back, submit the edit profile page
  6. get a "login here" page.
  7. login
  8. get redirected to the submitted page, pre-populated with all the posted data, and some kind of message saying to repost, since the data was not saved cause of session time out.

2.4. localStorage


  1. Sisyphus.js

3. Tools

  1. Form History Control
  2. Lazarus