Showing posts with label ajax. Show all posts
Showing posts with label ajax. Show all posts

Friday, October 06, 2006

Detecting user authentication expiration from an AJAX request

Problem:
How to detect that an AJAX request has been redirected to a login page by the ASP.NET's Forms Authentication?

Background:
Forms Authentication is a standard user authentication is ASP.NET. As a refresher, this authentication scheme utilizes cookie to track whether a user already login. A user requesting a secured page will be redirected to a login page if he/she is not authenticated yet. Once the user is authenticated, the server will redirect to the page that the user originally request.

The Forms Authentication works fine for normal ASPX pages. When the user is idle for a certain amount of time (the default is 30 minutes), the cookie is expired, and the user will be forced to relogin again.

In an AJAX application, the server also behaves the same way. When the cookie is expired, the server will automatically redirect to the login page. However, since the request is made through a XmlHttpRequest object, the browser does not automatically load the login page, instead the content of login page is retrieved by the XmlHttpRequest object.


Solution:
I use a HTTP custom header to differentiate a login page from other pages in the web application. By doing this way, Javascript can easily identify whether an AJAX request has been redirected to a login page (Well... it actually detects whether it receives the login page instead of the expected response).

In the code behind of the login page, add the following code:

// add a custom HTTP header to identify that this is a login page
Response.AppendHeader("IsLoginPage","1");

In the Javascript code, in the function that handles XmlHttpRequest's response, add the code in bold:

xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState==4) {
if (xmlHttp.status==200 && xmlHttp.responseText!=null) {
if (xmlHttp.getResponseHeader('IsLoginPage')=='1') {
alert('Your session has expired. Please relogin again');

} else if (typeof(responseHandler)=='function') {
responseHandler(xmlHttp.responseText);
}
}
}
};


I decided to simply display an alert so that the user is aware of the situation. My expectation is upon receiving this message, the user will explicitly relogin to the application.


Thursday, June 15, 2006

Ajax and Auto Save

The following article summaries our experience in working with auto save feature in the web application. New technology and new features always bring fresh challenges to developers and also good things for users, but they may also raise new issues that have never come up before. I hope by sharing this experience with you, you will be more aware with the issues while working on similar feature.


One of the recent challenge that my team had was to handle session timeout issue when our users spend too much time on a web form. As a background, a user session will time out when there is no communication (client request) with the server for a certain period. When time out happens, the user has to log in again and this action potentially destroys any unsaved changes the user has made on the web form.


We don't favor to increase the session time out, since this solution imposes a greater risk to our application. What we need is a feature or two that can handle session time out gracefully.


We come up with the idea of auto save after experiencing GMail for a while. The auto save feature has been in Microsoft Word as long as I can remember, so we often take it for granted, but it is a new and sexy feature for the web application.


In case you haven't seen how auto save works in GMail, this feature runs silently in the background. It will detect changes in the email content and periodically send the content to the server for saving. A short, non obstructive message will appear to indicate that the auto save is done.


So we made our mind to implement auto save in our web form. The web form is much more complex that Gmail's form. In the form, we have about 25 fields (textbox, dropdownlist, textarea) and a rich text box that can contains HTML.


Briefly this is what we did:


  1. A timer in set in Javascript that will invoke a function called saveData() every n-minutes.

  2. saveData() calls a home-grown Javascript form utility to extract the values of all fields into XML.

  3. We use AJAX to send the XML to the server.

  4. The server receives the XML and based on the status of the data does either one of the following:

    1. If the user does not explicitly save the data, we save the XML into a table that is created for the sole purpose of saving data temporarily.

    2. If the user has explicitly save the data before (for example, by clicking on the save button), we deserialize the XML into business object, and use the data access layer (DAL) class to save the data into proper tables.


  5. Upon completing the operation, the server returns a return status and the javascript displays the auto save message.


In my observation, it is important that the auto save message does not distract from the user's focus. We don't want the user to lose focus on the fields he/she is working only for the sake of auto save. The auto save feature should be made as transparent as possible.


Point 1-5 above is what we did initially with the auto save. When we used this feature for a while, we noticed that the audit log was filling up fast. This is because we always save to the database regardless whether the data has been changed.


We have two options to solve the problem. First option is to compare the values of the fields in the client side and send the XML only if we find differences. The second option is to compare the values in the server side. While the second option requires less effort, we find that this solution has potential issues. As the value comparison is done in the server side, the client needs to constantly send the XML data to the server side. This will increase the traffic and make the server busy unnecessarily. It will also make the user session never expires, opening the application for further exploitation. The first option is indeed more challenging but it will create a more efficient traffic and the user session still works properly.


Let's see the beauty of auto save in the following mini case study:


A user logs in to the application, enters data in the form, but he hasn't press the save button. After n-minutes, the auto save triggers and saves the data to the temporary table. Suddenly, there is a network disruption and the user loses his session.


After the network disruption is over, the user logs in to the application again and revisit the same form. This time the application checks the temporary table and finds the auto save data that belongs to the user. The application pops up a message, informing the user whether he/she want to recover the data or continue with the blank form. If the user chooses to recover the data, the auto save data is loaded and populated to the form. However, if he chooses to start with blank form, the auto save data is deleted.


Giving options to recover data or to start with a blank form is a nice to have feature, because in some cases the lost data is not worth to recover.


Does auto save solve session timeout issues? I can say partially. The session will still time out if the user does nothing, but with auto save the user will not lose all data. I have been thinking of another feature that can warn the user when the session is about to time out. This feature will complement auto save to make a really user friend form.

Saturday, February 25, 2006

Why I use out-of-band AJAX requests

In current project, I use a lot of out-of-band AJAX requests. In an out-of-band request, individual request does not flow into its own standard ASP.NET page life-cycle but instead calls another page and follows the flow of the corresponding page.

There has been a growing debate regarding the pros and cons of out-of-band request. In the cons side, the out-of-band request breaks ASP.NET model. Developers do not code in the usual manner they are used to do for years. Instead they have to create another page to server AJAX request. In my company, we call this page as 'handlers' or 'AJAX handlers', or simply 'AJAX servers' to less-technical people :) Whatever the name is, programming this handler is usually more raw and messy since we have to let go some nice ASP.NET features like ViewState that makes web programming easier and more intuitive (more like an event-driven programming).

In the pros side, the out-of-band request is more efficient since it only carries data that the handler need. It does not need to carry hefty payload from ViewState. The server side processing is also more efficient since it does not to reconstruct the state of the whole control hierarchy. Moreover, the handler also promote reusability and clear separation of responsibility, since a handler's only responsibility is to provide correct response based on received request. It does not need to know how the UI is rendered. Thus a handler can be used by several UIs.

So which kind of request to choose? It really depends on how you structure the content of the page. In a common ASP.NET project where one screen in the specification translates into one ASPX page, then you can safely avoid out-of-band request. Microsoft ATLAS does this. The programming model does not change dramatically.

However, the moment you want to promote reusability, you will start using ASCX (user controls) inside the ASPX and later, to promote even further reusability, use custom controls. In this case, the out-of-band request is a better option (and perhaps the only way to implement AJAX request). Consider that it is too expensive to reconstruct the whole page (and reinstantiate all user controls/custom controls in the page) only to serve a single AJAX request.

Tuesday, June 07, 2005

AJAX DropDownList

Just recently, I published a new article in CodeProject about implementation of AJAX (Asynchronous Javascript and XML) in a dropdownlist.

AJAX DropDownList is a custom control, inherited from System.Web.UI.WebControls.DropDownList. What differs this control from the normal DropDownList is the ability to fetch data asynchronously in the background without requiring any postbacks. Thus, an AJAX DropDownList can be dynamically populated from the client side using Javascript. Moreover, AJAX DropDownList implements Observer pattern to 'listen' to the change event of another AJAX DropDownList, and to 'broadcast' its change event to the other AJAX DropDownLists. This feature allows us to create a group of dependent dropdownlists, where a change in the first dropdownlist will trigger change on the second dropdownlist, and subsequently trigger change on the third dropdownlist, and so on...

Please read
the article in Code Project for more details.