1

I have a login-based site and I'd like to log the user out when they leave the site (i.e. close the browser or close the tab). I'm aware this isn't fool-proof by any means, but I want to set it up as best I can nonetheless.

I am using the following code:

$(window).unload(function() {
    //Send an Ajax request to logout.php
    $.ajax({
        type: "POST",
        url: "scripts/logout.php"
    })
});

And logout.php simply unsets the session.

This works fine when closing the website, but it works a little too well, meaning that it also fires when a page is reloaded or when an intra-site link is clicked. How can I prevent this behavior, i.e. check that the user's action is actually closing the browser or navigating away from the site, as opposed to reloading or visiting another site section?

sveti petar
  • 3,637
  • 13
  • 67
  • 144
  • Obviously that will fire every time the site is reloaded as the window will be initiated anew. Just rely on the browser sessions, those expire automatically when the browser is closed. – Kalkran Feb 17 '16 at 15:10
  • curious as to the php tag if there's no code to support the question, along with sessions. – Funk Forty Niner Feb 17 '16 at 15:10
  • @Kalkran I realize that now, the question is, is there any way to make Javascript differentiate between those events? As for browser session expiring, they don't expire for me when I close the tab or navigate to another website. – sveti petar Feb 17 '16 at 15:12
  • @Fred-ii- You're right, the problem is located in the front-end. Tags removed. – sveti petar Feb 17 '16 at 15:13
  • @jovan So, you believe that the problem only lies in the ajax and not with php/sessions? – Funk Forty Niner Feb 17 '16 at 15:14
  • @Fred-ii- The logout/login code works fine otherwise. It is only when I call it on unload that I get this issue. – sveti petar Feb 17 '16 at 15:15
  • Just use a session variable like 'reload = 1' and check it from page to page, if it is still present, don't log out. – Gary Hayes Feb 17 '16 at 15:16
  • @GaryHayes I don't follow. How will that help if the session is unset each time a link or reload is clicked? By the time the next page is opened, it's too late. – sveti petar Feb 17 '16 at 15:17
  • [See this answer on SO](http://stackoverflow.com/questions/1686687/how-can-i-get-the-destination-url-in-javascript-onbeforeunload-event). I don't think it's possible to detect what the user is doing when (s)he is navigating away from your page. It's not something that should logically be known to any website anyway. – Kalkran Feb 17 '16 at 15:18
  • Yeah, the session won't unset if they just close a tab... maybe use get to stay logged in. – Gary Hayes Feb 17 '16 at 15:19
  • If you want to log a user out when they navigate away or close their browser, you could implement a logout timer (set a `$_SESSION['lastactive']`) and check this every time a user refreshes your page. If a user stays on a single page too long they will be logged out as well though. You could repeatedly make an AJAX call to an update-script or something. – Kalkran Feb 17 '16 at 15:24
  • The session won't be unset if you use an if statement on your logout,php page. You can prevent the log out then redirect to the next page from there. There are many ways I would tackle this issue, but you'll have to show more code. – Gary Hayes Feb 17 '16 at 15:24
  • @Kalkran this is another good solution, depending on his needs, it may be the one he should use. I typically use set time out for about 10 minutes, then the screen darkens and asks if user is still there, giving them about 60 seconds to say yes, or it logs them out. – Gary Hayes Feb 17 '16 at 15:27
  • @GaryHayes The `logout.php` is currently just ` – sveti petar Feb 17 '16 at 15:38

1 Answers1

0

I just wanted to let everyone know how I solved this conundrum.

In the end, I ditched the idea of the unload function in Javascript and went for a combined JS/PHP solution.

While the user is on the site, this AJAX fires every 10 seconds:

$.ajax({
    type: "POST",
    url: "scripts/resession.php"
});

The target PHP updates the user's last_active stat in the database:

<?php
session_start();
include('../includes/db.php');

if(isset($_SESSION['isloggedin'])){
    $_SESSION['last_active']=time();
    mysql_query("update users set last_active='$_SESSION[last_active]' where id='$_SESSION[user_id]' ");
}
?>

On opening a user-only page on the website, we simply check whether the user's been active for the last 20 seconds. If not, that means they had left the site in the meanwhile and we log them out and redirect to the login page:

if(isset($_SESSION['isloggedin'])){
    $result = mysql_query("select last_active from users where id='$_SESSION[user_id]' ");
    $lainfo = mysql_fetch_assoc($result);
    //if more than 20s of inactivity, that means our user has left the site in the meanwhile and they should be logged out
    if($lainfo['last_active'] + 20 < time()){
        unset($_SESSION['isloggedin']);
        unset($_SESSION['user_id']);
        unset($_SESSION['last_active']);
        header("location:welcome.php");
        exit;
    }
}

It's not ideal, in that there's a 10-20 second period in which they can come back and still be logged in - but that actually has its perks, as there might be situations when the user forgets to do something and comes back immediately after closing, so it would be an annoyance for them to have to log in again in that case.

sveti petar
  • 3,637
  • 13
  • 67
  • 144