In my chat application i am having the logout button and it works fine.
Now I need to logout the application when I closed the browser window also..How can I achieve
After lots of search I wrote the below customized code in javascript and server side code for session kill in c#.
The below code is extended in case of same website is open in multiple tabs so the session is alive till one tab of website is open
//Define global varible
var isCloseWindow = false;
//Jquery page load function to register the events
$(function () {
//function for onbeforeuload
window.onbeforeunload = ConfirmLeave;
//function for onload
window.onload = ConfirmEnter;
//mouseover for div which spans the whole browser client area
$("div").on('mouseover', (function () {
//for postback from the page make isCloseWindow global varible to false
isCloseWindow = false;
}));
//mouseout event
$("div").on('mouseout', (function () {
//for event raised from tabclose,browserclose etc. the page make isCloseWindow global varible to false
isCloseWindow = true;
}));
});
//Key board events to track the browser tab or browser closed by ctrl+w or alt+f4 key combination
$(document).keydown(function (e) {
if (e.key.toUpperCase() == "CONTROL") {
debugger;
isCloseWindow = true;
}
else if (e.key.toUpperCase() == "ALT") {
debugger;
isCloseWindow = true;
}
else {
debugger;
isCloseWindow = false;
}
});
function ConfirmEnter(event) {
if (localStorage.getItem("IsPostBack") == null || localStorage.getItem("IsPostBack") == "N") {
if (localStorage.getItem("tabCounter") == null || Number(localStorage.getItem("tabCounter")) == 0) {
//cookie is not present
localStorage.setItem('tabCounter', 1);
} else {
localStorage.setItem('tabCounter', Number(localStorage.getItem('tabCounter')) + 1);
}
}
localStorage.setItem("IsPostBack", "N");
}
function ConfirmLeave(event) {
if (event.target.activeElement.innerText == "LOGOUT") {
localStorage.setItem('tabCounter', 0);
localStorage.setItem("IsPostBack", "N");
} else {
localStorage.setItem("IsPostBack", "Y");
}
if ((Number(localStorage.getItem('tabCounter')) == 1 && isCloseWindow == true)) {
localStorage.setItem('tabCounter', 0);
localStorage.setItem("IsPostBack", "N");
**Call Web Method Kill_Session using jquery ajax call**
} else if (Number(localStorage.getItem('tabCounter')) > 1 && isCloseWindow == true) {
localStorage.setItem('tabCounter', Number(localStorage.getItem('tabCounter')) - 1);
}
}
//C# server side WebMethod
[WebMethod]
public static void Kill_Session()
{
HttpContext.Current.Session.Abandon();
}
For this issue I tried 2 solutions: window.onbeforeunload event and sessionStorage
Since window.onbeforeunload is not only for closing the browser but also redirect, tab refresh, new tab, it was not a robust solution. Also there are cases which the event does not happen: closing the browser through the command line, shutting down the computer
I switched to using sessionStorage
. When the user logs in I set a sessionStorage variable to 'true'; when the application is loaded I would check to see if this variable is there, otherwise I would force the user to log in. However I need to share the sessionStorage variable across tabs so that a user is not forced to log in when they open a new tab in the same browser instance, I was able to do this by leveraging the storage event; a great example of this can be found here
Add your logout code to the on onunload event.
window.onunload = function () {
//logout code here...
}
In JQuery you can use the .unload() function. Remember that you don't have much time so you may send the Ajax request but the result may not reach the client.
Another trick is to open a small new window and handle the logout there.
window.open("logout url","log out","height=10,width=10,location=no,menubar=no,status=no,titlebar=no,toolbar=no",true);
If you want to disable closing the window (or at least warn the user), you can use this code:
window.onbeforeunload = function(event) {
//if you return anything but null, it will warn the user.
//optionally you can return a string which most browsers show to the user as the warning message.
return true;
}
Another trick is to keep pinging the client every few seconds. If no reply comes back, assume the user has closed the window, browser has crashed or there is a network issue that ended the chat session anyway. On the client side, if you don't receive this ping package, you can assume that network connection or server has a problem and you can show the logout warning (and optionally let the user login again).
I dealt with this issue recently in my angularJS app - The main issue was that I don't want to log you out if you refresh, but I do want to if you close the tab.. Ajax requests with onbeforeunload/onunload aren't guaranteed to wait for response, so here is my solution:
I set a sessionStorage cookie on login that is just a bool - set to true when I get login response
sessionStorage.setItem('activeSession', 'true');
Obviously, on logout, we set this flag to false
Either when controller initializes or using window.onload (in my app.js file) - I check for this activeSession bool.. if it is false, I have this small if statement - where if conditions are met I call my logout method ONLOAD instead of onunload
var activeSession = sessionStorage.activeSession;
if (sessionStorage.loggedOutOnAuth) {
console.log('Logged out due to expiry already')
}
else if (!activeSession) {
sessionStorage.loggedOutOnAuth = true;
_logout()
}
Basically, the "loggedOutAuth" bool let's me know that I just expired you on page load due to the absence of an activeSession in sessionStorage so you don't get stuck in a loop
This was a great solution for me since I didn't want to implement a heartbeat/websocket
Some websites are using the following script to detect whether window is closed or not.
if(window.screenTop > 10000)
alert("Window is closed");
else
alert("Window stillOpen");
You need to add the correct action instead of alert()
also take a look HERE - I think this is somthing you need to detect the window closing
I was with this problem here and I come with a different solution:
checkSessionTime();
$interval(checkSessionTime, 2000);
function checkSessionTime() {
var now = (new Date()).getTime();
if (!$localStorage.lastPing) {
$localStorage.lastPing = now;
}
if ($localStorage.lastPing < now - 5000) {
$localStorage.lastPing = undefined;
AuthService.logout();
} else {
$localStorage.lastPing = now;
}
}
I like this solution cause it doesnt add overhead pinging the server nor rely on the window unload event. This code was put inside the $app.run
.
I am using angular with a JWT auth, this way to me to log out just mean to get rid of the auth token. However, if you need to finish up the session server-side you can just build the Auth service to do one ping when finishing the session instead of keep pinging to maitain session alive.
This solutionsolves my case cause my intetion is just to prevent unwanted users to access someones account when they closed the tab and went away from the PC.