注销后防止后退按钮


Prevent back button after logout

我不希望用户在注销后通过单击后退按钮返回受保护的页面。在我的注销代码中,我正在取消设置会话并重定向到登录页面。但是,我认为浏览器正在缓存页面,因此尽管会话从注销中被销毁,但它仍然可见。

我能够通过不允许浏览器缓存来避免这种情况

header("Cache-Control", "no-cache, no-store, must-revalidate")

但是这样我就失去了浏览器缓存的优势。

请提出更好的方法来实现这一目标。我觉得,javascript客户端必须有一种方法来处理这个问题

在PHP而不是javascript中实现这一点。

在每个页面的顶部,检查用户是否已登录。 如果没有,则应将其重定向到登录页面:

<?php 
      if(!isset($_SESSION['logged_in'])) : 
      header("Location: login.php");  
?>

如您所提到的,注销时,只需取消设置 logged_in 会话变量,然后销毁会话:

<?php
      unset($_SESSION['logged_in']);  
      session_destroy();  
?>

如果用户现在单击后退,则logged_in会话变量将不可用,并且页面将不会加载。

我面临着同样的问题,花了一整天的时间弄清楚它,最后纠正如下:

在登录验证脚本中,如果用户经过身份验证,则为实例设置一个会话值,如下所示:

$_SESSION['status']="Active";

然后在用户配置文件脚本中输入以下代码片段:

<?php
session_start();
if($_SESSION['status']!="Active")
{
    header("location:login.php");
}
?>

上面的代码所做的是,仅当$_SESSION['status']设置为"Active"时,只有它会转到用户配置文件,并且此会话密钥将设置为仅当用户经过身份验证时才设置为"Active"...[注意否定['!'] 在上面的代码片段中]

注销代码可能如下:

{
    session_start();
    session_destroy();
    $_SESSION = array();
    header("location:login.php");
}

希望这有帮助...!!

这是我在应用程序中使用的一个简单的解决方案。

在登录 HTML 页面(或注销后重定向到的任何页面(的脚本标记中添加以下代码

<script>
    history.pushState(null, null, null);
    window.addEventListener('popstate', function () {
        history.pushState(null, null, null);
    });
</script>

它将禁用后退按钮。您将无法通过单击后退按钮返回。

注意:未在 Safari 上测试。

我认为您唯一的服务器端选择是不允许缓存。如果您使用的是Javascript繁重的应用程序,这实际上还不错,因为您的主HTML可能只是一系列JS调用,然后动态生成视图。这样,大部分数据(JS MVC 和核心代码(被缓存,但实际的页面请求不会。

为了添加到下面粘贴的评论,我建议在加载期间添加一个小型的 AJAX 调用,即使对于进入后端并检查会话的缓存页面也会触发该调用。如果未找到会话,则会将用户重定向。这是客户端代码,当然不是安全修复,但看起来更好。

你可以用你的良心摆脱这一点

如果所有其他方法都失败,一个便宜的修复方法是注销页面上的"出于安全原因请关闭此窗口"消息。 – izb 五月 9 '12 在 8:36

但就像N.B.说的

您不必禁用任何内容。如果他们返回,则会向他们提供受限页面的缓存版本。如果他们尝试单击它,则没有任何效果,因为不会设置适当的会话。– NB 五月 9 '12 在 7:50

您可以在每个受限页面上插入条件/函数,检查是否设置了适当的会话变量。这样,您可以打印页面的 2 个版本(一个用于有效用户,一个重定向到登录页面(

避免用户返回不是一个很好的理由,最重要的是根本不安全。

如果您在网站上执行每个"管理员"操作之前测试用户的会话,则即使用户点击后退按钮,看到缓存的页面并尝试某些操作,也应该没问题。

"捆绑某些东西"将返回错误,因为会话不再有效。

相反,您应该专注于拥有一个真正安全的后台。

这是一个简单快捷的解决方案。

在登录表单标记中添加target="_blank",以在不同的窗口中显示内容。 然后注销后,只需关闭该窗口,后退按钮问题(Safari浏览器(就解决了。

即使尝试使用历史记录也不会显示页面,而是重定向到登录页面。这对于Safari浏览器来说很好,但对于Firefox等其他浏览器,session_destroy();会处理它。

您需要

登录的页面,每 1000 毫秒使用 setInterval,并检查用户是否使用 ajax。 如果用户会话无效,请将其重定向到登录页面。

请注意,尽管用户在重置会话数据和/或 cookie 后无法更改任何内容,但他们仍然可能会看到登录用户在上次访问时访问的常规信息。这是由浏览器缓存页面引起的。

您必须确保在登录用户可访问的每个页面上添加标题,告诉浏览器数据是敏感的,他们不应该缓存后退按钮的脚本结果。添加很重要

header("Cache-Control: no-cache, must-revalidate");

请注意,除了此标头下的脚本的直接结果之外,其他元素仍将被缓存,您可以从中受益。看到您逐渐加载页面的某些部分,并使用此标头标记敏感数据和主 HTML。

正如答案所暗示的那样,取消设置全局变量$_SESSION logged_in部分可以实现注销,但请注意,首先,您不需要销毁 PHP session_destroy()文档中提到的会话

注意:您不必从常规代码调用 session_destroy((。清理 $_SESSION 数组,而不是销毁会话数据。

其次,您最好不要破坏会话,因为文档上的下一个警告会解释。

此外,unset()是一个惰性函数;这意味着它不会应用效果,直到下次使用有问题的(部分(变量。最好在敏感情况下使用赋值立即生效,主要是可能在并发请求中使用的全局变量。我建议你改用这个:

$_SESSION['logged_in'] = null;

并让垃圾回收器收集它,同时它作为登录用户无效。

最后,为了完成解决方案,这里有一些功能:

<?php
/*
 * Check the authenticity of the user
 */
function check_auth()
{
   if (empty($_SESSION['logged_in']))
   {
      header('Location: login.php');
      // Immediately exit and send response to the client and do not go furthur in whatever script it is part of.
      exit();
   }
}
/*
 * Logging the user out
 */
function logout()
{
   $_SESSION['logged_in'] = null;
   // empty($null_variable) is true but isset($null_variable) is also true so using unset too as a safeguard for further codes
   unset($_SESSION['logged_in']);
   // Note that the script continues running since it may be a part of an ajax request and the rest handled in the client side.
}