当用户在其中一个选项卡中注销时,如何从所有打开的选项卡中自动注销用户?

2022-08-30 12:50:00

我创建了一个登录页面,其中包括许多其他页面,其中包含检查会话的代码。如果用户没有会话,则所有页面都将重新加载并重定向到注销页面。此脚本每三秒调用一次。

我编写的代码工作正常,但我想以另一种方式实现它。当用户注销时,所有打开的选项卡都会重新加载/刷新,从而导致用户注销。这可能吗?

会话检查.php

<?php
session_start();
if(isset($_SESSION['username']) && $_SESSION['username'] != ''){
    echo "true";
}
else {
    echo "false";
}
?>

此代码位于每个页面页脚中:

<script>
    function gettatus(){
        $.get("sessioncheck.php", function(data){
            if(!data) {
                window.location = "logout.php";
            }
            setTimeout(function(){
                checkLoginStatus();
            }, 3000);
        });
    }
    $(document).ready(function(){
        gettatus();
    });
</script>

答案 1

当 ajax 有用时

每 3 秒向服务器发出一次 ajax 请求,仅在情况 1 中很有用。您已在不同的浏览器中打开选项卡 2.或在许多计算机中。3.或者您使用的是非常旧的浏览器

设置 Cookie 不起作用。

使用设置 Cookie 的方法不起作用,因为一个选项卡无法识别另一个选项卡中已更改的 Cookie。这是因为(使用getCookie获取cookie的位置)的选项卡A在没有向服务器发出请求的情况下不会更改。您可以打开SO的两个选项卡,并尝试在一个选项卡中设置,然后在另一个选项卡中查看。documentsetCookie('name', 'val', 1)document.cookie

如何让其他选项卡立即知道注销

如果您需要注销同一浏览器的所有选项卡,那么在选项卡之间传递信号会很棒。有几种方法,我想告诉你关于使用(演示在这里)。localStorage

您可以将侦听器附加到事件(在更改存储项时触发)并发送信号。storagelogout-event

localStorage.setItem('logout-event', 'logout' + Math.random());

每隔一个选项卡都会通过侦听器获取它。

window.addEventListener('storage', function(event){
    if (event.key == 'logout-event') { 
        // ..
    }
});

如果旧浏览器没有本地存储怎么办

您可以使用这两种方法 - 以及自动刷新,例如每60秒一次,以确保在不同计算机上打开选项卡时它有效。如果不起作用(非常旧的浏览器),则每3秒自动刷新一次。localStoragelocalStorage

下面的小提琴显示了如何处理它。

还有什么?

您可以使用 node.js + socket.io 在用户的所有浏览器之间发送信号。它可以快速工作,并将在每个设备上注销用户,但是处理起来比普通的jQuery要难一些。


答案 2

让我们考虑一下您正在使用php会话的东西,并且每次加载页面或在一段时间后检查以下代码

<?php
    session_start();
    if(isset($_SESSION['username']) && $_SESSION['username'] != '')
        echo true;
    else 
        echo false;
?>

因此,在注销.php文件时,您可能正在执行类似此类操作 unset($_SESSION['用户名']);和 session_destroy();

因此,当您的页面调用该检查php时,您会发现返回为false,并且以下用户将不再从任何浏览器和任何页面访问。对于自动注销,请尝试此操作

$sessionTTL = time() - $_SESSION["timeout"];
if ($sessionTTL > $inactive) {
    session_destroy();
    unset($_SESSION['username']);
    echo false;

注意:登录时必须将(例如)设置为全局变量$inactive = 6000;