29

I have a strange problem in my online test management system.

Some users in the test form (test.php) need long time to answer the question and submit the form.

After submitting the form the session is expired and user must login again

this is not a code problem

I set this value in top of all pages

ini_set('session.gc_maxlifetime', 18000);

Is there a way to refresh the session evrey 10 minutes without reloading the page in test form to prevent session expire?

Please help me

Thanks

NewUser
  • 3,729
  • 10
  • 57
  • 79
Mohammad Masoudian
  • 403
  • 1
  • 4
  • 7
  • May be do some ajax calls? Could you describe your script a little more? May be some code samples would help :) – Gogol Sep 26 '12 at 08:09
  • 1
    Interesting. I'm dealing with a similar problem but my opinion on the matter is that one should avoid automatically resetting the session timeout at an interval as that will effectively create an infinite session which will persist as long as the browser window is open. Instead I suggest that your max lifetime should be increased, and the timeout can be refreshed based upon user action. Even mouse move could do the trick, start a timer once the mouse is moved. Unless some user interaction component is included it creates a large security hole. Sessions are designed to expire. – Jesse Ivy Feb 09 '18 at 23:54

3 Answers3

42

You can use javascript XHR, or as others call it, AJAX.

Using ajax you can call a php script that refreshes your session every 10 minutes. :)


This is as far as i can go to "exact".

javascript

var refreshSn = function ()
{
    var time = 600000; // 10 mins
    setTimeout(
        function ()
        {
        $.ajax({
           url: 'refresh_session.php',
           cache: false,
           complete: function () {refreshSn();}
        });
    },
    time
);
};

// Call in page
refreshSn()

refresh_session.php

<?php
session_start();

// store session data
if (isset($_SESSION['id']))
$_SESSION['id'] = $_SESSION['id']; // or if you have any algo.
?>

Anyway, another solution would be to extend the session time for the test page only using the solution presented here

How do I expire a PHP session after 30 minutes?

Alex Khimich
  • 788
  • 9
  • 10
gianebao
  • 17,718
  • 3
  • 31
  • 40
  • 14
    In the PHP script, isn't it `session_start()` only enough? – lorenzo-s Aug 30 '13 at 15:46
  • 8
    `setInterval(function(){$.post('path/to/refresh_session.php');},600000);` - You can replace the whole JavaScript function by this one line – myfunkyside Jun 11 '14 at 06:45
  • 3
    @myfunkyside: Your oneliner also has the advantage that it doesn't keep piling up on the call stack. Granted, a recursive function with a delay of 10 minutes would take about 100 days to exceed the maximum stack size, but it's good practice to be careful with recursive functions. – okdewit Aug 17 '16 at 13:09
  • Though you did provide the correct answer, doesn't this create the potential for an infinite session? And isn't that bad? What if the user walks away from their machine? A week later the session will still persist. – Jesse Ivy Feb 09 '18 at 23:57
  • @JesseIvy This is a 6-year-old solution. – gianebao Feb 16 '18 at 15:18
  • 1
    Yes, it is a six year old solution @sheeks06 and that's why I thought it might be noteworthy to note that the correct way to maintain the timeout is by leveraging user action (such as mouse move, page transition, or calls to other endpoints) to call the endpoint, instead of, or in combination with setting an interval, that way, when the user goes dormant, the account will still timeout. Kicking the session by resetting the id still works. Hence the +1. Is there an even better way? Good answer. Maintaining the timeout is important, maybe the answer warrants an edit. :) – Jesse Ivy Feb 17 '18 at 16:59
  • It's just an emergency patch for another API I need to implement JWT on, which is what I use. In the Auth Header. – Jesse Ivy Feb 17 '18 at 18:16
  • I would like to see the answer updated to include @myfunkyside comment, as it worked for me right out of the box (disregarding the path adjustment) while I couldn't get the refreshSn function to work at all. Maybe because I have no experience with Ajax, and maybe because it's 7 years later, but still. – donutguy640 Jul 12 '19 at 13:47
  • 1
    it just work while keeping page opening , how to prevent destroy session when page closed? i mean how to keep this when page is not open? i tested gc_maxlifetime in php.ini but dose not work.! – Aria5h4h Jun 05 '20 at 14:06
16

All you need is this (uses jQuery for the $.post):

JavaScript (put this inside your onload-function or something)

setInterval(function(){
  $.post('path/to/refresh_session.php');
},600000); //refreshes the session every 10 minutes

refresh_session.php

<?php
  session_start();

  // if you have more session-vars that are needed for login, also check 
  // if they are set and refresh them as well
  if (isset($_SESSION['token'])) { 
    $_SESSION['token'] = $_SESSION['token'];
  }
?>

The biggest change is in the JavaScript--you don't need a whole function, just one line.


EXTRA INFO

Although I think it's enough to just call session_start() in the php, if I read this right (http://nl3.php.net/function.session-start):

The read callback will retrieve any existing session data (stored in a special serialized format) and will be unserialized and used to automatically populate the $_SESSION superglobal when the read callback returns the saved session data back to PHP session handling.

And during testing I only put the above code on my visitor page, and not on the admin page. But I had both pages open in the same browser (Chrome), and the admin page stayed logged in as well, at least for over an hour (didn't check any longer). BUT, I don't know if it still works if you only use session_start(), without manually refreshing any session-var at all..

Either way, I like to be sure that the session-vars I need are really still there:)

isherwood
  • 58,414
  • 16
  • 114
  • 157
myfunkyside
  • 3,890
  • 1
  • 17
  • 32
  • 1
    Your "EXTRA INFO" does not seem to be true. I am having the same issue. Created an ajax call (ping/pong) to the server trying to keep my session alive. For test prupose running every 5 minutes. Nomatter what, I get de-authenticated after about 2 hours. Now trying the session altering aprouch. – Flip Vernooij Aug 22 '14 at 11:30
  • @FlipVernooij so how did the "session altering approach" go? – Damilola Olowookere Dec 15 '17 at 11:06
0

Javascript:

function doStayAlive() {
  var request = new XMLHttpRequest();

  request.open('GET', 'stayalive.php', true);
  request.send();
}

timerStayAlive = setInterval(doStayAlive, 600000);  // 10 minutes

PHP: (stayalive.php)

<?php
  session_start();
  http_response_code(204);
?>

There is no need to "touch" session variables

Cyborgv2
  • 31
  • 4