javascript - 当用户将计算机置于 sleep 状态时,将用户从网站上注销

标签 javascript php laravel authentication

这是一件很奇怪的事。我们有一个 Laravel 网站,在该网站上,我们为每个用户设置了一个计时器,他们在启动前有 15 分钟处于非事件状态。

我们通过一个位于 React 组件页面上的计时器来实现这一点,它可以按照我们想要的方式工作,但现在我们遇到了一个新问题:如果用户登录并关闭笔记本电脑的盖子,网站应该启动他们.银行这样做,学校和大学这样做,政府网站也这样做。所以这是可能的,只是不确定如何。

我们确实使用网络套接字,使用 laravel-websockets图书馆和 echo 。我希望看到的是:

  • 关闭笔记本电脑后,您将进入登录屏幕。因此,下次您打开笔记本电脑并登录时,会在登录屏幕上看到浏览器。它不一定发生得那么快,但我们需要一种方法来向前端发送一些东西,基本上是告诉他们刷新页面,一旦 session 被终止,我们将 Laravel 的 session 生存期设置为 15 分钟。

  • 有些人在其他类似的问题中提出了建议:
  • to create a custom web-socket handler
  • 将 session cookie(在浏览器中)与后端的用户 cookie 进行比较。
  • 在前端运行一个计时器(我们这样做,当您关闭笔记本电脑盖时它就会停止)

  • 最流行的似乎是使用网络套接字,监听用户断开连接然后启动它们,这很好,但是你如何向暂停的浏览器发送请求然后启动它们?

    我找到了 requestIdleCallback()但同样,如果我已经在网站上有一个心跳计时器,我认为这不是我想要的。它也不适用于所有浏览器。

    我对如何做到这一点非常迷茫,我可以举的例子是:

    登录您的银行,让您的计算机进入休眠状态,等待 15-20 分钟,唤醒计算机,登录并看到您的银行现在在登录屏幕上显示您。 这就是我想要的 .但我不知道如何做到这一点。

    您无法从后端向“休眠”浏览器发送事件,虽然这必须是后端解决方案,但您如何更新前端,以便它们在重新唤醒笔记本电脑时显示在注销屏幕上还是电脑?

    最佳答案

    更新
    关于 WebSocket 请求,我假设您使用的是 Laravel WebSocketspusher . Pusher.io 不支持超时 ,您可以阅读这篇支持文章 "Do you plan to add a connection timeout feature to the Channels pusher-js client library?" .如果您启用 Laravel Debug模式( APP_DEBUG=true.env )并开始 laravel-websockets,您可以测试它从终端( php artisan websockets:serve ),所以你可以看到输出日志事件。如果您尝试合上笔记本电脑盖或将计算机设置为休眠模式( sleep ),您将不会看到有关此事件的任何消息。你不能用 pusher 做到这一点协议(protocol)。有 member_removed Presence event ,但这仅在您关闭选项卡或注销时触发。当然,您可以将客户端自定义事件触发到在线状态 channel ,但要做到这一点,您还需要在客户端设置一个计时器,并且您必须为 laravel-websockets 创建一个服务提供者。服务器喜欢这个 github 问题 "Exist a way to implement webhooks?" .

    Some people have suggested in other similar questions:

    ...

    • To have a timer running on the front end (we do, it just stops when you close the laptop lid)

    发生这种情况是因为客户端计时器在休眠时停止执行,因此它们从之前的位置继续。但是如果你使用日期变量来保存时间 ,当计算机进入休眠状态时,该变量不会更新,因此 通过检查日期变量 ,您就会知道它何时从 sleep 中醒来这与当前时间相比会有显着差异,并且会大于计时器间隔。
    在客户端实现时间逻辑
    您还可以看到此相关 Q/A 的实现:Can any desktop browsers detect when the computer resumes from sleep?
    您可以在客户端设置一个计时器,每分钟运行一次。 我们不会依赖定时器间隔 ,但该计时器将检查 外部范围日期变量 如果自上次计时器以来的时间跨度大于 15分钟;如果是,那么这意味着 浏览器/JS 因某种原因停止执行 ,可能是设备休眠( sleep ),然后您将用户重定向到注销路由。
    示例JS客户端代码:
    // Set a variable to check previous time
    let clientSession = new Date;
    
    // Setup the client session checking timer
    let clientSessionTimer = setInterval(() => {
      const now = new Date;
      // Get how many seconds have passed since last check
      const secondsSpan = (now - clientSession) / 1000;
    
      // If the 1 minute timer has exceeded 15 minutes trigger logout and clear timer
      if (secondsSpan > (60 * 15)) {
        // For some reason JS halted execution, so we'll proceed with logging out
        clearInterval(clientSessionTimer);
        window.location.href = '/logout/session'
      } else {
        // The timer runs as it should, update the clientSession time
        clientSession = now;
      }
    
    }, 1000 * 60);
    
    你可以检查这个简单的例子,但使用 1第二个计时器 15秒登出这里。最好在关闭盖子的笔记本电脑上测试它,然后在每两分钟 15 秒后再次打开它,因为如果你有很多程序正在运行,计算机需要一些时间来保存内存状态,以便完成休眠模式并停止执行。
    Web Worker 示例
    您甚至可以使用 Web Workers API设置一个网络 worker 更安全:
    页面JS代码:
    const logoutWorker = new Worker('logoutWorker.js');
    logoutWorker.onmessage = function (ev) {
    
      if (ev && ev.data === 'wakeup') {
        logoutWorker.terminate();
        // window.location.href = '/logout/session'
      } else {
        // The timer runs as it should, nothing to do
      }
    }
    
    网络 worker logoutWorker.js代码:
    let clientSession = new Date();
    
    let clientSessionTimer = setInterval(() => {
      const now = new Date;
      const secondsSpan = (now - clientSession) / 1000;
    
      if (secondsSpan > 15) {
        postMessage('wakeup'); // Send a message wakeup to the worker page
        clearInterval(clientSessionTimer); // Clear the timer
      } else {
        clientSession = now; // Update the clientSession timer variable
        postMessage('update'); // And post a message to the page ONLY IF needed
      }
    }, 1000);
    
    您还可以使用相同的 15 检查 Web Worker 示例。秒计时器 here .

    关于javascript - 当用户将计算机置于 sleep 状态时,将用户从网站上注销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60624694/

    相关文章:

    javascript - Javascript 重定向不适用于 IFrame,无需 IFrame 也可工作

    Javascript:数组中的多个过滤器

    javascript - ExtJS 还是 SmartClient?

    php - MySQL curdate() 和 now() 与 PHP date()

    PHP 5.3.5 PDO FETCH_OBJ 内存泄漏?

    laravel - 未捕获的语法错误 : Invalid or unexpected token in file compiled by Browserify

    php - 如何在不使用 Markdown 的情况下将纯文本版本添加到 Laravel 电子邮件

    javascript - 使用 jQuery $.each 与 Json 错误,有 1 个结果

    php - 如何在不指定数据库名称的情况下连接到 PostgreSQL?

    php - Laravel 流明照亮/控制台不会更新