Drupal 5: Logging out users after a period of inactivity

Here is the code I used in a module and theme to logout a user after 15 minutes of activity. The code uses jQuery, AJAX, sessions, and a menu callback function to keep track how it’s been since the user loaded a page.

The first piece of code I added was a menu callback to simply output the number of minutes of inactivity, which will be used by AJAX.

<?php
MYMODULE_menu() {
  // ...code...
  $items[] = array(
    'path' => 'sessionTimeout',
    'callback' => 'MYMODULE_sessionTimeout',
    'type' => MENU_CALLBACK,
    'access' => TRUE,
  );
  // ...code...
}
?>

Here’s the callback function used:

<?php
MYMODULE_sessionTimeout() {
  // ensure the user is logged in
  if (!$GLOBALS['user']->uid) die;

  // if session data does not exist, create it
  if (!isset($_SESSION['sessionTimestamp']) || strlen($_SESSION['sessionTimestamp'])==0) $_SESSION['sessionTimestamp'] = strtotime("now");

  // show how long it's been since a page loaded in in minutes
  echo intval((strtotime("now") - $_SESSION['sessionTimestamp'])/60);

  // this die is important, or your theme will be processed
  die;
}
?>

Next I created a function that will increment the session timestamp. As you can see, I used variable_get(). Whenever I feel like something should be configurable to the site administrator, I make sure to create an admin settings form (which I’m not showing in this example).

<?php
_MYMODULE_update_session_timeout() {
  // ensure the user is logged in
  if (!$GLOBALS['user']->uid) return;

  // define session timeout in minutes
  $sessionTimeout = variable_get('session_timeout', 15);

  // if session data does not exist, create it
  if (!isset($_SESSION['sessionTimestamp']) || strlen($_SESSION['sessionTimestamp'])==0) $_SESSION['sessionTimestamp'] = strtotime("now");

  $timeInactive = intval((strtotime("now") - $_SESSION['sessionTimestamp'])/60);

  if ($timeInactive > $sessionTimeout) {
    unset($_SESSION['sessionTimestamp']);
    drupal_goto('logout');
  }

  // update last page load
  $_SESSION['sessionTimestamp'] = strtotime("now");
}
?>

I wanted this piece of code to be executed on every page load, so I put it right at the top of my menu hook:

<?php
MYMODULE_menu() {
  // check session timeout
  if (arg(0)!='sessionTimeout') _MYMODULE_update_session_timeout();
  // ...code....
}
?>

In the head of my theme I added a line of code to set the session timeout so it will be available to jQuery. NOTE: I should have used drupal_add_js(), I’ll have to change my code.

<?php
<script type="text/javascript">
  var sessionTimeout = <?php print variable_get('session_timeout', 15); ?>;
</script>
?>

Lastly I added some jQuery to a javascript include file:

$(document).ready(function(){
  checkSession();
});

function checkSession() {
  result = $.ajax({
    type: "GET",
    url: "/sessionTimeout",
    success: function(html){
      if (parseInt(html)==html && html>sessionTimeout) {
        $.ajax({
          type: "GET",
          url: "/logout",
          success: function(html){
            alert("Sorry, you have been inactive for over " + sessionTimeout + " minutes. As a safety precaution, we have logged you out of the system. Sorry for the inconvenience.");
            window.location = "/";
          }
        });
      }
    }
  });
  setTimeout("checkSession()", 60000);
}

Now if the user leaves their browser open for 15 minutes without clicking on anything, they’ll get a popup window telling them their session expired, they’ll be logged out, and redirected to the homepage. If the user closes their browser and returns to the site a while later, they will also be logged out.

Updated: