Saturday, July 22, 2017

Session Management

HTTP Protocol/Web Server both are stateless by design, meaning that for web server, every request is a new request to process and they can’t identify if it’s coming from client that has been sending request previously. So you connect to the server, talk back and forth, then disconnect.

But real-world applications often do require state, we should know who the client is and process the request accordingly. For example, a shopping cart application should know who is sending the request to add an item and in which cart the item has to be added or who is sending checkout request so that it can charge the amount to correct client.

So, idea behind session management is to put requests from the same client in the same context, the concept of the HTTP Session exists.

All the HTTP Session is is the application state information relating to one particular client. A client being a single instance of an HTTP client application program. Or simply illustrated, if my desktop computer has IE and FireFox both communicating with the server, that's 2 clients. Regardless of how many windows and tabs they are using.

In order to associate a client's identify with a particular state-set on the server, you need some sort of identity. Hardware MAC addresses won't do it - they cannot be seen outside the local LAN segment. IP addresses won't do it either.

So lacking a reliable third-party identity mechanism, J2EE uses HTTPSession and jSessionId. The HTTPSession lives exclusively on the server and its most important feature is Map mechanism that holds objects stored in Session context and the User's login context - if the user has logged in via Container Security Services. So, Session management is server responsibility.

When the session is created, a session token(identifier/jSessionId) is generated and sent to the client (stored in a cookie). After that, in next subsequent requests between client and server, the client sends the session token(jSessionId) as an HTTP cookie in every HTTP request header, so that server can identify it. All session data is stored on the server, the client only stores the session token.

==> server is basically doing fetching the HTTPSession object from the session map via its key (jsessionid)

Server session map => (key, value) => (jSessionId, HTTPSession object)

This is an abstract Map - a really heavy-duty server might be paging sessions out in and out of files, databases or other persistent storage - or bouncing it between servers in a cluster, but from the application developer's point of view, it's there when it needs to be.

The jsessionid may NOT be the same value on every request/response cycle. It is not the case that the jsessionid is sent to the client, cached there and re-used on all subsequent requests. The jsessionid is whatever jsessionid was returned from the previous request response.In particular, for security reasons, when you switch to https (secure) transmission, the old jsessionid becomes invalid. A new jsessionid is returned from the secure response. Since the jsessionid is a "random" value with absolutely no information carried in it other than its own value, what the server is basically doing is fetching the HTTPSession from the session map via its old key (jsessionid), generating a new jsessionid, storing the session in the session map under the new key (jsessionid), and removing the old key/value from the map. Actual order and mechanism may vary, but that's the net effect.

There are several ways through which we can provide unique identifier in request and response.

User Authentication – This is the very common way where user can provide authentication credentials from the login page and then we can pass the authentication information between server and client to maintain the session. This is not very effective method because it won't work if the same user is logged in from different browsers.

HTML Hidden Field – We can create a unique hidden field in the HTML and when user starts navigating, we can set its value unique to the user and keep track of the session. This method can’t be used with links because it needs the form to be submitted every time request is made from client to server with the hidden field. Also it’s not secure because we can get the hidden field value from the HTML source and use it to hack the session.

URL Rewriting – We can append a session identifier parameter with every request and response to keep track of the session. This is very tedious because we need to keep track of this parameter in every response and make sure it’s not clashing with other parameters.

Cookies – Cookies are small piece of information(key/value pair) that is sent by web server in response header and gets stored in the browser cookies. When client make further request, it adds the cookie to the request header and we can utilize it to keep track of the session. We can maintain a session with cookies but if the client disables the cookies, then it won’t work.

Session Management API – Session Management API is built on top of above methods for session tracking. Some of the major disadvantages of all the above methods are:

    Most of the time we don’t want to only track the session, we have to store some data into the session that we can use in future requests. This will require a lot of effort if we try to implement this.
    All the above methods are not complete in themselves, all of them won’t work in a particular scenario. So we need a solution that can utilize these methods of session tracking to provide session management in all cases.

Understanding JSESSIONID Cookie

A "JSESSIONID" is the unique id of the http session. "Session information is scoped only to the current web application (ServletContext), so information stored in one context will not be directly visible in another another."

So when you first hit a site, a new session is created and bound to the SevletContext. If you deploy multiple applications, the session is not shared.

JSESSIONID cookie is created/sent when http session is created. Session is created when your code calls request.getSession() or request.getSession(true) for the first time. If you just want to get the session, but not create it if it doesn't exist, use request.getSession(false) -- this will return you a session or null. In this case, new session is not created, and JSESSIONID cookie is not sent.

Note: Every call to JSP page implicitly creates a new session if there is no session yet. This can be turned off with the session='false' page directive, in which case session variable is not available on JSP page at all.

No comments:

Post a Comment

Web Development

Design Phase:- Below all these represent different stages of the UX/UI design flow:- Wireframes represent a very basic & visual repr...