CSC 2720 Building Web Applications Managing Users' States – Cookies, URL-Rewriting, Hidden Fields and Session Management APIs
login.jsp bye.jspshow_acct.jsp Login Failed Logout Successful Login A typical web application involves more than one servlet. How should these servlets share data with one another? e.g., How does show_acct.jsp knows which user has successfully logged in and which user's account to show?
HTTP – A Stateless Protocol Web servers don't retain information about users between requests. Each HTTP request is like a phone call and the server hangs up the phone after serving each request. Web application developers need alternative methods for maintaining users' states. Cookies URL-rewriting Hidden fields in HTML forms Platform/language specific APIs for managing sessions
Program Logic Architecture of Stand-Alone Program User Interface and Presentation State Information (Data) All the components of the program work in the same memory space and share data. There is only one copy of data per application.
Web App (Business Logic) Architecture of Web Application Client B (User Interface and Presentation) Clients and servers have their own memory space. Client A (User Interface and Presentation)
Web App (Business Logic) Architecture of Web Application Client B (User Interface and Presentation) State Information (Data) How and where should we keep the state information that uniquely define an application for client A and B respectively? Client A (User Interface and Presentation) ?
Web App (Business Logic) Architecture of Web Application Client B (User Interface and Presentation) Client A (User Interface and Presentation) State info Approach #1: Clients kept the state info Clients sent the state info back to the server-side program in every request Server-side programs update the state info and sends them back to the clients to keep State info
Web App (Business Logic) Architecture of Web Application Client B (User Interface and Presentation) Client A (User Interface and Presentation) id2 Approach #2: Server keeps the state info Clients keep a unique ID (generated by the server) Clients pass ID back to server on every request Server-side programs look up state info stored in the local memory based on received ID. id1 State info id1 id2
Maintaining States and Session Tracking Approach #1 can be achieved through Cookies URL-rewriting Hidden Fields in Form Disadvantages: Require sending large amount of data which may include sensitive info between the client and the server on every request. Approach #2 can be achieved through High-level APIs for maintaining sessions by the Servlet
Cookies HTTP cookies are data sent by a server (on behalf of the server-side programs) to a browser to keep. The browser keeps the data for a period of time. The browser sends back the cookies to the server on every request (unless the cookie support is turned off). The cookies are embedded in the HTTP header (and therefore not visible to the user).
Cookies Shortcomings User may turn off cookies support. Data are kept with the browser Users using the same browser share the cookies. Limited number of cookies (20) per server/domain and limited size (4k bytes) per cookie Client can temper with cookies Modify cookie files, use JavaScript to create/modify cookies, etc. Notes Don't always rely on cookies as the client may have turned off cookies support. Don't store sensitive info in cookies
URL-Rewriting Data are appended to the URL e.g.: Data are kept along with the "page" Each time, a server-side program needs to Retrieve all state info from the URL Update the state info Write the state info back to the URL in all links that appears in the page (including the URL in the form "action" attribute) Shortcoming: Limited number of characters in an URL Not suitable for sensitive info
Hidden Fields in HTML Form Data are encoded as hidden fields in HTML form as: Shortcoming: Always need a form. <% String attemptParam = request.getParameter("attempt"); int attempt = 0; if (attemptParam != null) attempt = Integer.parseInt(attemptParam) + 1; // Assume no error in conversion %> Login ID Password " />
Session (Supported by the Servlet Container) A session is a period of time in which all activities happened within the period by the same client is considered "related" (typically belong to the same application.) Session Tracking – keeping track of users as they traverse from one web page or servlet to another within a website (or using a web application). Clients keep a unique "session id" generated by the server. The "session id" is sent back and forth between the client and the server through methods like cookies or URL- rewriting.
Creating and Obtaining Session object // e.g., in processRequest/doGet/doPost methods HttpSession session = request.getSession(); HttpServletRequest public HttpSession getSession(); Returns the current session object. If there is no current session object, create a new one and return it. In JSP, the "session" object is implicitly made available. We can store data to be shared among servlets/JSP in the session object.
Session object: Storing and Accessing Data // We can store objects in the session object session.setAttribute("username", name); session.setAttribute("login-attempt", new Integer(0)); String name = (String)session.getAttribute("username"); session.removeAttribute("username"); HttpSession public void setAttribute(String name, Object value); public Object getAttribute(String name); public void removeAttribute(String value); Works like a hash table except that the key is a string. You do not have to know what the generated session ID is.
More HttpSession Methods public Enumeration getAttributeNames(); Returns names of all attributes set in the session object public String getID(); Returns the unique session ID generated by the servlet container. public boolean isNew(); Returns true if the clients does not yet know about the session. public void invalidate(); Makes the session object invalid. Future use to this session object will result in IllegalStateException thrown.
More HttpSession Methods public void setMaxInactiveInterval(int seconds) Sets how long the session object can stay inactive before becoming invalid. Any user request to the resources that belong to the same web application would activate the session object. By default, the maximum inactive interval is set to 1800 seconds (30 min) If seconds is -1, then the session will only terminate when the client terminates (when the user closes the browser). public int getMaxInactiveInterval(); Returns the max inactive interval in seconds.
Using Session When Cookies is Disabled Use URL-rewriting method to pass session ID to client Use when cookies is disabled. HttpResponse public String encodeURL(String url); Call this method to create a new URL string with session ID appended to "url". Only append when necessary (e.g., when the client's browser does not support cookies or turns off cookies support).
Combined Use All of Cookies, URL-rewriting, Hidden Fields, and Session objects can be simultaneously used in a web application. Cookies: Can persist data for long period but is not suitable for keeping sensitive data or large amount of data. URL-rewriting: Keep data along with page Hidden Fields: Keep data along with page (can keep more data but requires HTML form) Session Objects: Keep "short-live" data shared among the servlets within a web application for a particular client.
Summary Session Management Cookies URL-Rewriting Hidden Fields in HTML Form High level APIs in Java and HttpSession Objects. Reference
Sending Cookies to Browser Standard approach: Cookie c = new Cookie("name", "value"); c.setMaxAge(...); // Means cookie persists on disk // Set other attributes. response.addCookie(c); Simplified approach: Use LongLivedCookie class: public class LongLivedCookie extends Cookie { public static final int SECONDS_PER_YEAR = 60*60*24*365; public LongLivedCookie(String name, String value) { super(name, value); setMaxAge(SECONDS_PER_YEAR); }
Reading Cookies from Browser Standard approach: Cookie[] cookies = request.getCookies(); if (cookies != null) { for(int i=0; i<cookies.length; i++) { Cookie c = cookies[i]; if (c.getName().equals("someName")) { doSomethingWith(c); break; }
public static String getCookieValue( Cookie[] cookies, String cookieName, String defaultVal) { if (cookies != null) { for(int i=0; i<cookies.length; i++) { Cookie cookie = cookies[i]; if (cookieName.equals(cookie.getName())) return(cookie.getValue()); } return(defaultVal); } Reading Cookies from Browser
Methods in the javax.servlet.http.Cookie getDomain/setDomain This property indicates the domain within which this cookie should be presented. (Default is the domain of the current server) getMaxAge/setMaxAge Gets/sets the cookie expiration time in seconds A negative value means that the cookie is not stored persistently and will be deleted when the browser exits. (Default) A zero value causes the cookie to be deleted. getName Gets the cookie name. Cookie name can only be set through the constructor.
Methods in the javax.servlet.http.Cookie getPath/setPath Gets/sets the path to which the cookie applies. The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's subdirectories. A cookie's path must include the servlet that set the cookie getSecure/setSecure Gets/sets a flag that indicates whether the cookie should only be sent using a secure protocol, such as HTTPS or SSL. getValue/setValue Gets/sets value associated with the cookie. If you use a binary value, you may want to use BASE64 encoding. With Version 0 cookies, values should not contain white space, brackets, parentheses, equals signs, commas, double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same way on all browsers.