In the second part of this tutorial on state and session management, we’ll further examine how cookies can be used to maintain state information between servlet requests, as well as some of the security implications of storing state data in cookies. We’ll also examine the topic of session management, and the advanced session-tracking features that the Servlet API offers.
Long-lasting cookies
By default, the cookies created by Java servlets will expire when the browser exits. Often, however, it’s handy to have this data persist for days, weeks or even months later. For example, a cookie that tracks user preferences should remain until the next visit. We can manually specify an expiration date, using the
Cookie.setMaxAge( int ) |
// Store color preference for one year
Cookie cookie = new Cookie ("color", "blue");
cookie.setMaxAge ( 60 * 60 * 24 * 365 );
// Add cookie to response
response.addCookie (cookie);
Security implications of storing state information in cookies
When dealing with mundane details, like a counter, it’s perfectly safe to store data in cookies. However, if the state information contains unique identifiers, such as a User-ID, then it can represent a strong security risk. If that User-ID authorizes access to a particular resource, then anyone who runs the Web browser can gain access. Under ideal situations, only a single user has access to a particular machine, but in shared environments (such as Internet cafe terminals, or offices), other people can access the browser and masquerade as a particular user.
This poses a potential security risk — but one that can be guarded against. As mentioned earlier, it is possible to specify an expiration date for the cookie. Once the expiration date is reached, the cookie is discarded from the browser. By default, cookies created by Java servlets will expire once the browser exits. However, in a shared environment where browsers remain open, this represents too great a security risk. The solution is to specify a very short expiration date (for example, in two minutes) and to periodically refresh the cookie as new requests come in.
// Create a cookie containing the userID
Cookie cookie = new Cookie ("userID", getUserID() );
// Specify a three minute timeout
cookie.setMaxAge ( 180 );
// Send back to the browser
response.addCookie(cookie);
For added security, it is also important to provide a "logout" function. This allows users to close their account, so that no further access can be gained without specifying a password or being authenticated. This is important as it is possible for another user to come along before the cookie has expired (though forgetful users still have the safeguard of a timeout). To void a cookie, simply specify a maximum age of zero.
// Void the cookie and send it back to the user
userid_cookie.setMaxAge (0);
response.addCookie(userid_cookie);
For simple tasks, cookies are a useful mechanism for storing simple state data. To store data securely, however, involves extra effort. A better mechanism is session management.
State versus session management
Session management allows a "virtual connection" to be established between browser and servlet. Rather than storing state information in cookies, hidden fields, or hyperlinks, a session identifier is assigned to each user. This identifier is then used to track individual requests and match them to a session. However, sessions persist for a limited period of time and are associated with a single user. No state information needs to be sent across the network — such information can be stored within the servlet and looked up as required.
This approach offers two big advantages over stored state variables in forms, hyperlinks, or cookies:
- simplicity for the developer
- less network utilization, as state data is not sent repeatedly.
The session approach is simpler for the developer, as there is no need to constantly refresh cookies or to write code to expire them. As state information isn’t sent to the browser and then echoed back to the server, less bandwidth is consumed. The Servlet API provides support for session-tracking, in the form of the
javax.servlet.http.HttpSession |
Overview of HttpSession
Session-tracking is made extremely easy with the
HttpSession |
Creating an HttpSession
Creating a new session is relatively straightforward. The
getSession(boolean) |
javax.servlet.http.HttpServletRequest |
boolean |
// Get the session for this client
HttpSession session = request.getSession(true);
Storing and retrieving data from a HttpSession
Once a session has been established, state data can then be added or removed. Like cookies, it is represented by a key-value pair. A single key maps to a single object — but this object can be an array if storing multiple values is necessary.
// Store userID in current session
session.putValue ("userID", request.getParameter("userid") );
Retrieving values is almost as easy. Using a string key, the contents of state data can be returned using the
getValue(String) |
// Return the list of items in shopping trolley
Vector vec = (Vector) session.getValue("list");
// Check to see if value exists
if (vec != null)
{
// Code to process contents would go here …
}
Other issues with HttpSession
By default, session-tracking is accomplished using cookies. This process is transparent for the developer — no extra code to store and retrieve cookies need be written. However, if cookies are disabled or not supported, every hyperlink must be encoded to include a session identifier. Without this, the session becomes lost. The
HttpServletResponse.encodeUrl(String) |
// HttpServletResponse.encodeUrl adds session data automatically
response.encodeUrl ( "/servlets/MyServlet" );
Developers should also be mindful of the fact that sessions are for storing temporary data, not for data that lasts for a long period of time. Sessions will not persist once the browser or servlet terminates, so any important data should be saved to disk or to a database. To allow easy retrieval of data at a later date, a username/password could be established, and a session created once the identity of the user is authenticated. Any changes to state data would be saved once the session closes, and accessed again at a future point in time.
Putting session-tracking to work
To demonstrate session-tracking with the
HttpSession |
NB: To test URL-rewriting, cookie support must be disabled, and the servlet engine must be capable of supporting it.
Listing 1: HttpSessionExample.java (See page 2)
Figure 1. Demonstration of session-tracking using HttpSession.
Summary
Whether you choose to create your own session-tracking mechanism using cookies or to use the
HttpSession |
About the author
David Reilly is a software engineer and freelance technical writer living in Australia. A Sun Certified Java 1.1 Programmer, his research interests include the Java programming language and networking & distributed systems. He can be reached via e-mail at java@davidreilly.com.
Listing 1 HttpSessionExample.java by David Reilly. |
||
|