Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

destroy session on window close?

Tags:

php

I have a created a login system in php with logout functions etc. But I need the session to be destroyed on window close. This needs to be "instant" or as fast as possible to change the users status to offline. I dont really want to set a time on the session as this is annoying for the user having to login all the time.

Any suggestions welcomed, thanks. =)

like image 832
Elliott Avatar asked Jun 06 '09 13:06

Elliott


People also ask

Is session destroyed when browser is closed?

Browsers deletes the session cookies when the browser is closed, if you close it normally and not only kills the process, so the session is permanently lost on the client side when the browser is closed.

Is possible to keep session even after the browser is closed?

It's oxymoron. Session stands for "until browser is closed". Session is something that expires.

How do you destroy a session?

Destroying a PHP Session A PHP session can be destroyed by session_destroy() function. This function does not need any argument and a single call can destroy all the session variables. If you want to destroy a single session variable then you can use unset() function to unset a session variable.


1 Answers

By default all session cookies sent by PHP are deleted when the browser closes. But as far as I see, you want to show notifications on other browsers. This is a little bit harder and not quite nice. You'd have to use the window.onclose event handler and issue an Ajax request (I believe it should be a synchronous request) to the server to signal the window closing. And synchronous calls aren't that nice...

On the other hand, the other browser will have to pull the server with other Ajax request to see when a certain user has logged off.

All these Ajax requests make for an ugly solution.

Update:

As Thorarin and Jonathan Fingland said, there may be problems with multiple windows (not tabs, as window.onclose fires on windows not tabs), but I believe there's a solution to this problem too. If the first window sets a cookie number_of_windows = 1, that is incremented for each opened window, then on window close, the Ajax request is fired only if number_of_windows equals to 1, otherwise it just decrements number_of_windows.

Update 2:

The above solution would, indeed, have troubles with multiple open tabs. I'm thinking how to alleviate that.

Update 3:

OK, I figured out some sort of solution but it's not working in IE6, don't know about other IE version. The below snippet keeps track of the number of open windows and tabs (except for IE which doesn't update document.cookie in real time between windows, but I believe it could be solved with some IE proprietary features). Then on each page unload, which means even navigating from page to page on the same web site, the script checks to see how many open windows are. If it's the only open window/tab, then it issues an Ajax request. This is the first part of the solution. Now, the second part.

On the server-side, the script that the Ajax call is requesting, should update some entry in a DB saying that the user may have closed the page. How do you figure whether she's not just accessing a new page on your site? Simple, on every page access you check the DB for "maybe logged out" values for that session, and if there are you flag them as false (the user is logged in), otherwise the user keeps being logged out in the DB (true flag).

It's messy but it's the single solution that came to my mind, as there's no way I could determine a page reload or the like in JavaScript. Also, I didn't do extensive testing, is more an idea. Anyway, I wouldn't recommend this solution. An Ajax request for every changed page is overkill and literally doubles the hits on the server, without counting the polling done by other browsers.

Here's the snippet. By the way, bakery.js is a small wrapper for document.cookie. You may find its source here on github.

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="bakery.js"></script>
<script type="text/javascript">
var logout = function() {
    var xhr = new XMLHttpRequest;
    xhr.open("GET", "logout.php", false);
    xhr.send(null);
};

window.onload = function() {
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0;
    IGS.Bakery.setCookie("winNumber", winNumber + 1);
};

window.onunload = function() {
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0;
    IGS.Bakery.setCookie("winNumber", winNumber - 1);

    if (winNumber === 1) {
        logout();
    }
};

var showCookies = function() {
    alert(IGS.Bakery.getCookie("winNumber"));
};
</script>
</head>
<body>

<a href="#" onclick="showCookies();">show</a>

</body>
</html>

Forgot to mention. window.onclose is not cross-browser.

like image 71
Ionuț G. Stan Avatar answered Sep 26 '22 08:09

Ionuț G. Stan