会话超时时如何自动刷新

Posted

技术标签:

【中文标题】会话超时时如何自动刷新【英文标题】:How to auto refresh when session time out 【发布时间】:2016-02-09 19:29:35 【问题描述】:

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

我有会话输出代码:

$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();

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

【问题讨论】:

what will I add so that when it refresh it will go to the header.是什么意思 什么是$inactive?是几秒还是几分钟? 早上好先生..我想知道我将在我的代码中添加什么,所以当会话结束时它将刷新先生..它将转到localhost/fmsgroup/fmsystempanamed/logout/endsession.php 不确定我是否正确理解了您的问题,但是,header("Location: http://localhost/fmsgroup/fmsystempanamed/logout/endsession.php"); 已经表现为页面刷新。也许,您的问题在于确定超时会话的逻辑,是吗?详细说明,以便我们确定真正的问题。 先生...页面...我的代码是什么?在那个代码中......当会话超时......当用户点击某个按钮时,时间页面将刷新......先生,我怎样才能......自动刷新它? 【参考方案1】:

这取决于您的会话实现。

    基于文件

没有过期钩子或回调事件,所以你只能使用ajax轮询,在你的情况下,服务器将重定向页面

    基于redis的

redis 2.8+ 有 keyspace 通知,所以如果你观察你的 session 数据库,你可以在 session 过期时收到通知。

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

或者可能还有另一个:

设置你的 session.gc_maxlifetime 等于 session.cookie_lifetime,这样当 session 过期时,cookie 也应该同时过期,这样 js 就不必从服务器轮询,而是可以定期检查本地 cookie。

【讨论】:

先生可以像我的代码一样站点一些示例代码..当会话超时..它会自动刷新...因为..当会话结束时..页面没有重新加载.. 【参考方案2】:

我认为最好的选择是 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";
?>

【讨论】:

【参考方案3】:

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

我知道这是一篇旧帖子,但我搜索并没有找到简单的答案。我在这里为其他看起来的人发帖。这是一个纯 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 身份验证并设置计时器的页面时带来了麻烦)。

<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。

【讨论】:

以上是关于会话超时时如何自动刷新的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 3.1 - 发生会话超时时自动重定向到登录页面

使用refreshToken颤动firebase自动刷新用户会话

休眠(mysql)刷新与提交中的自动增量

使用 AJAX 自动刷新在 Web 应用程序上超时会话的方法

如何在会话超时时关闭所有活动的引导模式?

如何在 Chocolatey 安装后刷新 PowerShell 会话的环境而无需打开新会话