Commit 57996fe9 authored by Andrew Nicols's avatar Andrew Nicols
Browse files

MDL-44642 session: Add a client-side session keepalive system

For pages where there will be significant user interaction in which the
server is not updated, it may be necessary to poll the server periodically
to touch the session.

This makes use of the existing checknet script which was designed for
checking network connectivity but fits into this use-case reasonably well.
parent 8f06fffb
......@@ -847,4 +847,41 @@ class manager {
\core\session\manager::set_user($user);
$event->trigger();
}
/**
* Add a JS session keepalive to the page.
*
* A JS session keepalive script will be called to update the session modification time every $frequency seconds.
*
* Upon failure, the specified error message will be shown to the user.
*
* @param string $identifier The string identifier for the message to show on failure.
* @param string $component The string component for the message to show on failure.
* @param int $frequency The update frequency in seconds.
* @throws coding_exception IF the frequency is longer than the session lifetime.
*/
public static function keepalive($identifier = 'sessionerroruser', $component = 'error', $frequency = null) {
global $CFG, $PAGE;
if ($frequency) {
if ($frequency > $CFG->sessiontimeout) {
// Sanity check the frequency.
throw new \coding_exception('Keepalive frequency is longer than the session lifespan.');
}
} else {
// A frequency of sessiontimeout / 3 allows for one missed request whilst still preserving the session.
$frequency = $CFG->sessiontimeout / 3;
}
// Add the session keepalive script to the list of page output requirements.
$sessionkeepaliveurl = new \moodle_url('/lib/sessionkeepalive_ajax.php');
$PAGE->requires->string_for_js($identifier, $component);
$PAGE->requires->yui_module('moodle-core-checknet', 'M.core.checknet.init', array(array(
// The JS config takes this is milliseconds rather than seconds.
'frequency' => $frequency * 1000,
'message' => array($identifier, $component),
'uri' => $sessionkeepaliveurl->out(),
)));
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Ensure that session is kept alive.
*
* @copyright 2014 Andrew Nicols
* @package core
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('AJAX_SCRIPT', true);
require_once(dirname(__DIR__) . '/config.php');
// Require the session key - want to make sure that this isn't called
// maliciously to keep a session alive longer than intended.
require_sesskey();
// Update the session.
\core\session\manager::touch_session(session_id());
......@@ -82,6 +82,7 @@ function confirm_sesskey($sesskey=NULL) {
*/
function require_sesskey() {
if (!confirm_sesskey()) {
header('HTTP/1.1 403 Forbidden');
print_error('invalidsesskey');
}
}
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -77,6 +77,8 @@ Y.extend(CheckNet, Y.Base, {
_performCheck: function() {
Y.io(this.get('uri'), {
data: {
// Add the session key.
sesskey: M.cfg.sesskey,
// Add a query string to prevent older versions of IE from using the cache.
time: new Date().getTime()
},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment