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.