Session Timeout Error in Ajax Applications

Hourglass

I recently discovered a major issue in many of my(and others) Ajax apps - not handling Session timeout properly. Lets say that you are using PHP as the backend. It has a 20 minute time limit for sessions(by default). If the user does not make any requests in that time, the session will get timed out. In normal, web 1.0, non-ajax applications, this is not a problem. If the session variable is not set, the code will do a redirect to the login page. But in Ajax applications, this becomes a problem.

This problem affects only the applications that uses logins and user authentication within their Ajax apps. Also, if you are using polling in any page, that page should not be affected. each polling request will be considered as an interaction.

Find if your App has this error

Login into your application - don't use remember me if your app has that feature. Next, go to a page where you will be able to send an Ajax request. Now wait for about half an hour without interacting with the site. Don't click on any links, don't go to other pages of the site - don't do anything. After half an hour, make the Ajax request. If the page acts weirdly(JavaScript Error, invalid return data, etc), your app has the problem.

How it should be...

Ideally, this is what the code should do in such cases.

The problem is that this should be done for every single request. If you already have an application that has this issue, there is a considerable amount of coding ahead of you.

Solution

success/error Design Pattern

I use a success/error design pattern for Ajax requests - each response is in JSON format and has a minimum of two elements in it - ie 'success' and 'error' - like this...

{
"success":"Task created successfully",
"error":false
}

The return handler function will be something like this...

function ajaxReturn(data) { //data is the 'eval'ed object of the responseText
	if(data.error) {
		//The 'showErrorMessage' handles the error.
		//showErrorMessage() will return true for a critical error and false for non-critical error.
		if(showErrorMessage(data.error)) return; 
	}

	//Do whatever you want with 'data'
	alert(data.success);
}

I then set up the 'showErrorMessage' function to handle the 'session timeout' error with a redirect.

function showErrorMessage(error_message) {
	if(error_message == 'User not logged in' || error_message == 'SESSION_TIMEOUT') {
		alert("Your session was timed out due to inactivity. Please Login to continue"); //Show an error message - or not - your choice.
		document.location.href = '/login.php'; //...and redirect to login page.
		return true;

	} else if(error_message == 'another error') {
		//Handle 'another error'

	/* ... */

	} else {
		$("error-message").innerHTML = error_message; //Default error handling - just show the error message to the user.
	}

	return false;
}

When using AHAH

If you are using the AHAH method, it could get a bit more complicated. The best thing to do is to change to a JSON based approach. But if you cannot do that, the only method I can think of is return a login form as the Ajax response. This form will get inserted into the document. I will not recommend this method - the problems with this method is too numerous to list here.

Do you know any other method to solve this problem?

Comments

Dashifen at 24 Apr, 2007 02:42
I know that when using the Prototype framework, you can trigger the onFailure handler by reporting any of the 40x HTTP errors. A HTTP 403 error seems appropriate as it indicates that the action was forbidden, in this case because the session timed-out. Then, the onFailure handler can handle the relogin process. Plus, since that framework provides the ability to register a global handler (see the Ajax.Responders object) you can easily add an onFailure handler to all Ajax objects which don't already have one.
Reply to this.
Fernando Franzini at 26 Apr, 2007 05:01
There are many problens when you use some API/Frameworks to handle ajax requests for you like DWR or Ajax4JSF. You must figure out in api doc to find somenthing that can you use like this function.
Reply to this.
Philippe Morvan at 26 May, 2007 05:12
For the timeout testing purpose, to the best of my knowledge, you can simply delete the corresponding session line ID, if you have access to the DB, which presumably you have. This will spare you the half hour!
Reply to this.
Jansan John at 31 May, 2007 08:16
hi..

i also faced this issue in one of my recent project. and i had rewrite a major part
of the code for handling this issue. anyway its good and informative...
Reply to this.
Robin Casey at 03 Jul, 2007 10:18
what if.. timeout: What about having a ajax script accessing a (blank) page that uses the session every X seconds? Let it return a 1 on success, and continue below:

what if.. cache deletion: You can also save serverside echoed (as encrypted as needed) passwords as clientside vars, to sign in automatically when the timeout above would report an error.

Cheers,

Robin.
Reply to this.
Comment


Comment




Comment Formating : HTML tags a, strong, em, b, i, code, pre, p and br allowed. Other tags will be shown as code(< will become &lt;). Urls, Line breaks will be auto-formated.