Reputation: 1057
My web application logs user logins and logouts on a database table, so that we keep track of user activity.
This works well when users explicitly login or logout, since the underlying authentication code is responsible for these logging events.
However, when the user leaves the computer idle for 30 minutes, the web session will expire and we'll have one Login event without the corresponding Logout event.
The only strategy I've thought for resolving this is to have a javascript event that triggers before the 30 minutes defined in the web.xml and that kicks the user out before the session expires. However, that has the limitation of needing javascript, and when someone uses multiple tabs it can have some unexpected results (i.e., user is using tab2 and session is expired in tab1).
What would you suggest for this case?
Upvotes: 1
Views: 2076
Reputation: 20862
You want to use an HttpSessionListener
. It's a standard interface defined by the Servlet Specification for exactly this kind of situation.
See below for a caveat.
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class LogoutListener implements HttpSessionListener {
@Override
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
// NOTE: You need to store some kind of user identification
// in the session. My example just has a "username"
// in here.
String username = session.getAttribute("username");
// If the username is null, there was no logged-in user
// to log-out (e.g. non-authenticated user).
if(null != username) {
// NOTE: Obviously, this needs to call your existing
// "logout"-recording code. Just an example.
MyDBUtilities.registerLogout(username, System.currentTimeMillis());
}
}
@Override
public void sessionCreated(HttpSessionEvent event) {
// Ignore
}
}
If you use the code above, you'll find that users who don't explicitly log out will get a single logout record, and users who do explicitly log out will get two. Why? Because you are likely using your "logout" action to write the "logout" record and then the session listener runs immediately afterward and makes a second audit entry.
There are two obvious solutions to this problem:
Upvotes: 2
Reputation:
use a session listener to update the database when the session expires.
This is a simple example of how to implement session.
https://www.mkyong.com/servlet/a-simple-httpsessionlistener-example-active-sessions-counter/
Upvotes: 1