Praveen Chinthala Praveen Chinthala - 12 days ago 4
Java Question

Session Handling Issue(To update DB row) - Session closes along with browser

I am using a database to store user details including username and password. It also has a

Security_check
column which has "logged_out" as default.

Whenever a user logs in I modify the
Security_check
value to "logged_in" from the page where i validate user (servlet). Whenever the user hits the logout button I explicitly change
Security_check
to its default value.

But when the user closes their browser without logging out, then there is a big problem because the
Security_check
column value for that user is still "logged_in" and after that when that user tires to log-in they will get an error message stating that you are already logged in (because i check the
Security_check
before allowing any user to log-in, and in this case they are already logged in). So he can't log-in and also he can't log-out because the session got expired when he closed the browser. So what should I do?

Below is the code for HttpSessionListener class, which is not working:

package com.svc.session;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.sql.*;
import javax.servlet.http.HttpSession;


public class Session_Invalidator implements HttpSessionListener
{
public Session_Invalidator()
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(Exception e)
{
}
}

public void sessionCreated(HttpSessionEvent se)
{
}

public void sessionDestroyed(HttpSessionEvent se)
{
HttpSession session = se.getSession();
String uName = session.getAttribute("userName").toString().trim();

Connection con = null;
PreparedStatement stmt = null;

try
{
// i am using a space between the colon and odbc because if
// I don't it will be converted to smile, so ignore the space
con = DriverManager.getConnection("jdbc: odbc:CMS","","");
stmt = con.prepareStatement("update Users set security_check=default where login_name=?");
stmt.setString(1, uName);
int no = stmt.executeUpdate();
} catch(Exception e)
{
}
}
}

Answer

It think you have two alternatives.

  1. Choose a very short session timeout (like one or two minutes) and implement something like a ping from your webpages to your server with AJAX calls. So while the user browser is open and shows your webpage your server will always get a ping notification and remains the session open. If the user closes the browser your server session will get a timeout very soon. But there is still a short delay. The downside of this approach is that you will produce more traffic and you have to find an appropriate session timeout value. A too short value can cause a session timeout if there are some network delays. A too long value raises the time period in which the user is unable to relogin.

  2. This is my favorite solution: Don't be so restricted to disallow a relogin at all. Don't store the logged in state in your database. If the user wants to relogin after closing the browser then a new server side session is created and the user gives login credentials and good is. The old session will be destroyed after timeout. This is the default behaviour if you use container based security. I recommend to use container based security (JAAS). Why do you want to disallow a relogin?

Here are some links regarding JAAS:

Comments