如何在会话超时时自动刷新

时间:2015-11-09 07:26:59

标签: php

我正在尝试在会话超时时自动刷新页面。我看过其他帖子,但我认为我们不是同一个问题。

我有会话输出代码:

$inactive = 10;
if( !isset($_SESSION['timeout']) )
$_SESSION['timeout'] = time() + $inactive; 

$session_life = time() - $_SESSION['timeout'];

if($session_life > $inactive)
{  session_destroy(); header("Location: http://localhost/fmsgroup/fmsystempanamed/logout/endsession.php");     }

$_SESSION['timeout']=time();

我将添加什么,以便在刷新时将转到标题。

3 个答案:

答案 0 :(得分:0)

这取决于您的会话实施。

  1. 基于文件的
  2. 没有过期挂钩或回调事件,因此您只能使用ajax轮询,在您的情况下,服务器将重定向页面

    1. redis的基
    2. redis 2.8+具有键空间通知,因此如果您观看会话数据库,您可以在会话过期时收到通知。

      但是,这将是一个昂贵的解决方案。因为你有PHP进程阻塞来等待事件,所以不推荐。

      或者可能还有另一个:

      将session.gc_maxlifetime设置为session.cookie_lifetime,因此当会话到期时,cookie应该同时到期,因此js不必从服务器轮询,而是可以定期检查本地cookie。

答案 1 :(得分:0)

已编辑订单,因此现在可以使用!

我知道这是一篇过时的文章,但我进行了搜索,但没有找到简单的答案。我在这里张贴给其他人。这是一个纯PHP解决方案。我看过很多帖子,说您不能用纯PHP做到这一点,这是不正确的。我放弃了一个PHP解决方案,然后它像砖头一样击中了我。

我使用最少的会话登录时间,我们会说1800秒(30分钟) 在$ _SESSION ['expire']中设置为($ now + 1800)

$now=time();
$_SESSION['expire'] = ($now + 1800);
$timeremaining=($_SESSION['expire'] - $now);
$buytime=1800; // sets how much time we add with a page refresh/load
$addtime=900;  //sets at what point we add time with a page refresh/load. 
//In this example a page reload will not add time ($buytime) until we reach 900 
//or less seconds remaining. at which time we will add 1800 seconds

在$ _SESSION ['expire']显示距当前时间15分钟(900秒)之后,我们现在可以刷新页面的$ buytime或加载另一个页面(带有$ buytime代码)。一旦我们达到会话超时之前的15分钟或900秒,页面刷新就不会增加时间,直到我们再次低于15分钟900秒。如果某人不是每15分钟加载一次页面,则应该使他们的登录超时。

if ((($_SESSION['expire'] - $now) <= $addtime) && (($_SESSION['expire'] - $now) > 0))
{
$_SESSION['expire']=($_SESSION['expire'] + $buytime);
$timeremaining=($_SESSION['expire'] - $now);
}

现在,因为我执行刷新操作还有其他事情,例如如果登录无效,则返回登录屏幕,因此我在变量中设置了以下内容。在这种情况下,我们假设有效的登录名

$refreshurl='<meta HTTP-EQUIV="REFRESH" content="'.$timeremaining.'; url=login.php">';

我们现在可以使用上面的$ refreshurl变量来构建页面内容。 在最后一次页面加载之后,PHP页面刷新将在$ timeremaining发生,并迫使我们返回登录页面,因为我们在页面标题中回显了$ refreshurl,还强制重置所有会话变量,以防万一。

<a href="'.$_SESSION['pageurl'].'">

上面的PHP确实带有URL变量,或者如果您想要的JavaScript甚至可以维护页面锚(这确实给我带来了麻烦,该页面在进行实际php身份验证并设置计时器的页面的首次加载时给我带来了麻烦。) / p>

<a href="javascript:history.go(0)"> 

使用此解决方案,重新加载当前页面会增加时间,或者加载新页面会增加时间。如果使用页面刷新或新加载的页面(具有类似的代码)进行更新,则标题也会进行更新。设置新页面的刷新时间。

现在,页面将刷新,并以新的过期时间(以秒为单位)开始倒数新的标头(应用$ buytime并重置$ timeremainiing后,将设置$ refresurl。当倒数至0时,页面将重新加载登录页面。同样在登录页面上,我未设置所有会话变量,然后在开始时销毁了会话;还对所有页面进行了多次检查,以确保会话未过期,并且使用有效密码登录了有效用户。显然还不够。此处未包含安全代码!

我还运行了一个javascript工具(如下所示)以显示剩余时间,并且当会话计时器达到0或当前时间时,该javascript的php包装器也会破坏会话。

checklogin.php

session_start();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$now = time();
$logininsec = ($_SESSION['expire'] - $now);  //gets remaing session in seconds
$loginrefresh=60 to update the dynamic page data every minute
// makes $loginmessagetxt appear on page dynamically using Javascript
if (( $requireauth == 'yes' ) && ( $_SESSION['loggedin'] == 'yes' ) && ( $_SESSION['expire'] > ($now + $addtime) ))
{
$loginmessagetxt='<span style="color:#080; font weight:bold">Session expires in '.round(($logininsec / 60),  0, PHP_ROUND_HALF_DOWN).' minutes</span>' ;
}


else
{
$loginmessagetxt='<span style="color:#F00; font weight:bold">Session has expired</span></td <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/login.php"><span style="color:#777AFF; font-weight:bold">'.$login.'</span></a>'; 
session_unset($_SESSION["loggedin"]);
session_unset($_SESSION["expire"]);
session_unset($_SESSION["username"]);
session_unset($_SESSION["password"]);
session_unset($_SESSION["userpath"]);
session_destroy();
$loginrefresh = '7200';  //this just keeps the javascript from running so frequently when logged out
}
echo "retry: $loginrefresh\ndata: {$loginmessagetxt}\n\n";

然后在页面上,我们还需要以下内容来显示登录时间剩余g

echo "<td><div id=\"loginStatus\">Checking Login Status</div></td>";

具有以下脚本支持

<script type="text/javascript">
if(typeof(EventSource)!=="undefined") {
    var statusSource = new EventSource("checklogin.php");
    statusSource.onmessage = function(event) {
            document.getElementById("loginStatus").innerHTML = 
event.data;
    };
}
else {
    document.getElementById("loginStatus").innerHTML="Unsupported";
}

因此,尽管我在解决方案中确实使用了一些Javascript。基本解决方案可在无JavaScript支持的情况下使用。除非您要动态显示剩余时间。

我可能还会补充说,我也倾向于在其他代码中编写100多种破坏会话的方法,因为我怀疑其中很多方法是否非常安全。有很多方法可以解决页面刷新和运行javascript的问题。

答案 2 :(得分:0)

我认为最好的选择是AJAX。您可以在页面上创建一个间隔,该间隔将向服务器发送请求。

javascript部分将放置在html文档的BODY部分中

<script>
function keepAlive() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
          if (this.responseText === "pong") {
              // session refreshed
          } else {
              // something wired happened
          }
     }
  };
  xhttp.open("GET", "ping.php", true);
  xhttp.send(); 
}
// set an interval that runs keep alive every 10 minutes
setInterval(function() {keepAlive()}, 600000);
</script>

然后您将拥有响应请求的ping.php文件

<?php
session_start();
echo "pong";
?>