At which point of time is a session counted as inactive? - java

Ok, In Java, I don't understand what actions tell that a session is and isn't alive.
I used to think that if user has never touched the page and after a period of time, the session will expire.
session.setMaxInactiveInterval(15*60); //15 mins
But let say there is a page call ajaxChat.jsp which has a functions to send data back and forward between client and server.
The UserA logined & created a session. He then can enter the ajaxChat.jsp. UserB sometimes send messages to UserA via interface on ajaxChat.jsp.
UserA just lives the ajaxChat.jsp & do something else. Hoever, every 5 mins the UserB send a message to UserA.
The question is that if UserA just leaves ajaxChat.jsp there without touching it for more than 30mins, then will the session of User A expire? Note that every 5 mins, ajaxChat.jsp receives a new message from UserB.
I don't understand how Java Session works when it is counted that the session expires?
Which actions tell that a session is or isn't alive?
At which point of time is a session counted as inactive?
What if user has never touched the page but the page has some Ajax calls periodically in the background?

Here Ajax code in ajaxChat.jsp is responsible for sending and receiving the message. So both USer-A and User-B are using the output of the Servlet generated after JSP translation and compilation. So, do not think it as ajaxChat.jsp page is making communication between the two users.
For the server request that comes after every 5 minutes marking the activity from user irrespective of the call by normal user action or Ajax call. Both are equivalent for the server. Meaning that the server will not count it as inactive session.
If you want to have your application with behavior of expiring session after 15 minutes, you will need to handle on your own.
You can manage a map in application context (key as JSESSIONID cookie value) with your last activity time of user from the specific pages/calls which are interpreted as actions from the user not from Ajax Chat. Testing every time the difference (Last Activity Time - Current Time) and marking the session expired explicitly as sesion.invalidate().

Related

Destroy user session stored in database on window close

In our JAVA web application we maintain users' session in a database table active_sessions. And we do not allow multiple sessions per user. what it means is, if you are already logged in with a particular user account, you cannot open a new session with the same account. In case somebody does, we display error 'User already has an active session'. When user clicks on Logout his entry from table active_sessions is removed. But in case where user closes the window without logging out his entry remains in the table active_sessions. So any attempt to login in future results in an error 'User already has an active session'. Any tips on how to destroy user session in database in case he closes the browser window without logging out.
Edit: After reading all the posts it seems there is no clean way to restrict single session per user.
Use the 'onbeforeonload' JavaScript event which can perform an AJAX call to your server to delete the entry. This event will however be executed each time the page is unloaded so if you don't have a SPA then you'll need to ignore the event for href and such.
Agree with Almas however that your approach is dangerous in the sense that it is not possible to enforce this 100%. E.g. if the user kills the browser process then even this JS event would not be published.
Furthermore, a user can simply use another browser to bypass your 'protection'.
In the server side users HTTP session is normally invalided after a certain period of idle time. You can implement http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html and register it in web.xml to receive notifications about session create/destroy etc. In your listener implementation you could delete the table entry on session destroy event.
The basic thing about HTTP is that it is request/response protocol.
i.e. Things are changed/accessed only by making a request to the server. This 'limitation' makes your requirement interesting. There can be two workarounds for this:-
Poll the server at a repeated interval through an AJAX call. As long as you application keeps getting the polling AJAX request you can assume that the window is open.
Use javascript (window.onunload ) to fire an event to destroy user session when the browser is closed.
Using onuload

Different sessions for different tabs of the same browser

I am using timestamp till nano second as a user session, say tab A has session1 and user opens tab B say this session is session2 and now session1 gets only inactivated after some file upload activity is done at this point of time I want the session2 be still active.
How do I do this without using cookies?
have you looked into html5 sessionStorage/localStorage ?
these apis sport a client-side storage facility pretty similar to cookies which you can employ to manage sessions. the lifetime of the database is either the lifetime of the respective tab/window (ssessionStorage) or the interval between two consecutive deletions the pertaining browser data; the latter may depend on the browser preferences (eg. automatically after closing the tab/window in privacy mode or upon express user request).
for a start, mdn has something to say about it. there also is a full-fledged tutorial on html5rocks.
the gritty in-depth w3c standard details all about the programmatic (javascript) interface.
the api do not provide facilities to exchange information between client and server. one option to handle this part would be encoding the information into urls (client -> server) or http headers (server -> client) being called/received through ajax.
a final word of warning: for security reasons, do not store authenticating data this way.
say tab A has session1 and user opens tab B say this session is session2
This is already impossible. Both tabs will be in the same session. If tab B created a new session due to a login for example, tab A will now be in the new session.
and now session1 gets only inactivated after some file upload activity
It won't happen.
is done at this point of time I want the session2 be still active.
It still is. Session 1 will have been destroyed if it's different from session 2.

Webapp: When user submits a second request before the 1st one is "finished" the browser shows the output of the first req. why?

Summary
In our web application when the user clicks "faster" than the page loads, apparently the browser shows the first request to the user (according to some error messages we get). I would have expected that to be the second request.
More background information
We have a Struts1 web application. In the user session we put the current context of the user interaction.
request.getSession().setAttribute("context", <something>);
For instance, the app shows a list of master records, and the context holds information about the user. When the user clicks on a master record, we save the the information about that record in the user session object. In the JSPs we often would assign the context object to a local variable. This needs casting to the specific type (e.g. MasterRecordDTO or UserDTO):
<% MasterRecordDTO dto = (MasterRecordDTO) request.getSession().getAttribute("context"); %>
The user can then drill down into details views of that master record. We have a breadcrumbs showing sth like list > master > detail. These are links so the user can navigate using breadcrumbs.
Now when in that situation the user clicks first on "master" and quickly enough on "list" he gets an ClassCastException saying
"UserDTO cannot be cast to MasterRecordDTO"
in the MasterRecord-JSP, which means that when the MasterRecord-JSP assigns the dto variable in the first request, the second request has already set the context session attribute to a UserDTO object.
Question
I would have expected that the browser would "abandon" the first request and shows the result of the second request to the user (the list of master records in this example). Can anybody explain this to me?
Update
The breadcrumb links are in another HTML Frame. We have this issue with Internet Explorer 7. I tried it with Firefox 11 but apparently it doesn't even submit the second click.
I guess it's a general concurrent programming situation.
The browser send 2 request simultaneously to server, the server use 2 threads to handle 2 request.
request/thread 1 set session attribute context to MasterRecordDTO
request/thread 2 then changed it to UserDTO (Here's the source of the problem)
request/thread 1 continue running, it will cause ClassCastException occured.
request/thread 2 continue running, it will generate a successful response to client. (but the browser does not show it)
The behaviour of browser is not controled by your application, it just show the result of response 1 (sometimes may be response 2, it's also a concurrent situation, because most current browsers are multi-threading designed).
Try to use request scope to store such context information to get an expected result.

Session expired - How to terminate the session in the original tab of the browser

I have a web app in which I have set the maximum inactivity time to 10 min. This is just for testing purposes. Basically, if the session has timeout and I click on a link, the following window browser checks if the session is valid. This is also working fine. If this happens, I get a message saying "session has expired, please login again". But the orginal window stays open and if I click on the same link, then this time is letting me see the page, even though I have not logged in again. Why is this?
I am using the session.invalidate() if the session is expired, to make sure all attributes are removed, but this is not working somehow.
I using the following part of the code at the beginning of the page:
if(request.isRequestedSessionIdValid() == false)
{
response.sendRedirect("expired.jsp");
session.invalidate();
return;
}
This is working the first time this page is loaded, but if I click on the link again to load it once more, this condition is not met, despite the session being timeout.
Could you please give any advice?
Update: My webapp works the following way:
User gets to the index.jsp page and uses an ID and password to access the system, then there is a BRMspace.jsp page where there is a folder structure for the user to access depending on the documents they are after. By clicking on each folder, a table with a database populated is displayed for the user to download the documents they want.
The issue I am having is that after 10 min of inactivity, if the user clicks on one folder on the initial screen, the database is not displayed, instead I get a message saying that session has expired and I am redirected to the login page, which is ideal. However, if I click on the same folder again, this time I get the usual table with the data and all documents. It seems that after one click, the inactivity time is not longer valid.... so I am not sure how to do... I am using session.invalidate() to delete all data about the session, but obvioulsy is not working.
I need the user to be redirected to login page again after the inactivity time no matter where the user clicks on.
This is an update:
Hi there, I have to re-take this question, which has been very helpful to resolve 90% of my original issue, but I still have one left.... on my web application, when user logins, they have a list of options to click on, each click takes them to a new tab which are different .jsp files... if session has expired, these tabs show the expired.jsp file, which is perfect... however, the original tab, the one that is shown after the user logins, stays live, I mean, it does not show that the session has expired... what can I do in this case?...
A web session doesn't have anything to do with any login or access credentials. It simply means that the container has data saved for you that can be retrieved if you pass in the correct session token (either by cookie or request parameter). If you have been inactive on the site for a period of time (in your case 10 minutes), that data is discarded and if you check for a sessions validity, you will discover whether the data is still around or has been discarded. If the session has expired, the container will automatically create a new session for you to handle future requests. And if another request is sent to the server before the timeout expires, that requested session will not be invalid.
If you are trying to prevent people from access a page when they have not logged in, you actually need to put some value into the session that says they have authenticated, and check that value. Just checking whether their requested session is valid is not sufficient.

Invalidate a session

I have a jsp servlet based application, with session time out of 30 mins, I want to invalidate the session as soon as a person closes the browser window intentionally or accidentally (OS shutdown/close from tast manager/powerdown)
Can I put a check for that and invalidate the session?
It is not possible to handle this scenario .
There are some browsers which provide this setting as their preference , but you can't handle this programitically.
At max:
You can make a poll from page(may be header) same as gtalk in gmail as soon as connection closes wipe that session out.
Why do you want to do that, you have already configured that in server that ,session should stay idle for 30 mins,after that it will expire in server.
if you want to do that use the following javascript or jquery(better for cross browser) , when the browse close event happens send an ajax request to invalidate session by running following code in jsp
(request.getSession(false).setMaxInactiveInteral(0);)
From javascript
<body onbeforeunload="doAjaxCall();">
(or)
jQuery(window).bind("beforeunload", function(){
// Do ajax request and dont wait for the response.
});
You can implement the server push ajax polling , for example think that session is going to expire in another 2 seconds , send a server side request to client to invalidate the cookie and also in the server you can invalidate the session.
if ( (getcurrentTime() - session.getCreationTime()) > 2000 ) {
}
While the page is rendered , get the maxinactiveinterval and then set the value to the JavaScript variable , then use setInterval function , pass the inactiveinterval value to function , once the timeout happens you can set the cookie to expire.
No I don't believe you can do that as there are no hooks available in the browser to get it to send a disconnect notification (of some sort) when it closes and I don't think there is a server-side mechanism to interrogate recent sessions to test their connection status.
If you are using tomcat 5.0/5.5/6.0 container, the cookie generated by tomcat session manager to track the session (JSESSIONID) is a per-session cookie (browser memory only cookie) instead of a persistent cookie (write to disk). That's because the session manager does (hardcoded) setMaxAge(-1), so that the generated HTTP-response contains:
Set-Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; Path=/ and no Expire=date.
So when the browser is closed (all browser windows, or just the window containing the cookie, depending on the variuos browser implementations), the cookie - and the session - are lost. [*]
This has nothing to do with <session-timeout>, which is a setting that tells the tomcat server-side session manager to expire sessions when idle for more time than specified.
[*] they will still be persisted on disk on the server-side, till session-timeout expires, but there wont be a request with a cookie activating them.

Categories