views:

954

answers:

3

Can somebody tell me how can I close/kill the session when the user closes the browser? I am using stateserver mode for my asp.net web app. The onbeforeunload method is not proper as it fires when user refreshes the page.

+10  A: 

You can't. HTTP is a stateless protocol, so you can't tell when a user has closed their browser or they are simply sitting there with an open browser window doing nothing.

That's why sessions have a timeout - you can try and reduce the timeout in order to close inactive sessions faster, but this may cause legitimate users to have their session timeout early.

Oded
+4  A: 

As said, the browser doesn't let the server know when it closes.

Still, there are some ways to achieve close to this behavior. You can put a small AJAX script in place that updates the server regularly that the browser is open. You should pair this with something that fires on actions made by the user, so you can time out an idle session as well as one that has closed out.

Gus
A: 

As you said the event window.onbeforeunload fires when the users clicks on a link or refreshes the page, so it would not a good even to end a session.

[http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx][1] describes all situations where window.onbeforeonload is triggered. (IE)

However, you can place a JavaScript global variable on your pages to identify actions that should not trigger a logoff (by using an AJAX call from onbeforeonload, for example).

The script below relies on JQuery

/*
* autoLogoff.js
*
* Every valid navigation (form submit, click on links) should
* set this variable to true.
*
* If it is left to false the page will try to invalidate the
* session via an AJAX call
*/
var validNavigation = false;

/*
* Invokes the servlet /endSession to invalidate the session.
* No HTML output is returned
*/
function endSession() {
   $.get("<whatever url will end your session>");
}

function wireUpEvents() {

  /*
  * For a list of events that triggers onbeforeunload on IE
  * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
  */
  window.onbeforeunload = function() {
      if (!validNavigation) {
         endSession();
      }
  }

  // Attach the event click for all links in the page
  $("a").bind("click", function() {
     validNavigation = true;
  });

  // Attach the event submit for all forms in the page
  $("form").bind("submit", function() {
     validNavigation = true;
  });

}

// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
    wireUpEvents();  
});

This script may be included in all pages

<script type="text/javascript" src="js/autoLogoff.js"></script>

Let's go through this code:

  var validNavigation = false;

  window.onbeforeunload = function() {
      if (!validNavigation) {
         endSession();
      }
  }

  // Attach the event click for all links in the page
  $("a").bind("click", function() {
     validNavigation = true;
  });

  // Attach the event submit for all forms in the page
  $("form").bind("submit", function() {
     validNavigation = true;
  });

A global variable is defined at page level. If this variable is not set to true then the event windows.onbeforeonload will terminate the session.

An event handler is attached to every link and form in the page to set this variable to true, thus preventing the session from being terminated if the user is just submitting a form or clicking on a link.

function endSession() {
   $.get("<whatever url will end your session>");
}

The session is terminated if the user closed the browser/tab or navigated away. In this case the global variable was not set to true and the script will do an AJAX call to whichever URL you want to end the session

This solution is server-side technology agnostic. It was not exaustively tested but it seems to work fine in my tests

Daniel Melo
Important to note that you have to make it a *synchronous* Ajax request, or it's extremely unlikely to get fired off at all. And of course, synchronous Ajax requests are ugly, they completely tie up the UI of the browser.
T.J. Crowder
@T.J. Crowder: ugly is an understatement when your server's having problems and a typical response time is more than 5 seconds :-)
Andy E
Valid comments. How about a sync AJAX call with very small timeout?. Please consider that the proposed solution does not aim to resolve all the issues with orphans sessions. It would cover only a percent of them (user actively closes the browser and the logout URL responds ultra fast)
Daniel Melo