The*_*ebs 11 javascript php authentication laravel
这是一件很奇怪的事。我们有一个 Laravel 网站,在该网站上,我们为每个用户设置了一个计时器,他们在启动前有 15 分钟处于非活动状态。
我们通过一个位于 React 组件页面上的计时器来实现这一点,它按我们的意愿工作,但现在我们遇到了一个新问题:如果用户登录并关闭笔记本电脑的盖子,网站应该引导他们. 银行这样做,学校和大学这样做,政府网站也这样做。所以这是可能的,只是不确定如何。
我们确实使用 web sockets,使用laravel-websockets库和 Echo。我希望看到的是:
有些人在其他类似的问题中提出了建议:
最流行的似乎是使用网络套接字,监听用户断开连接然后启动它们,这很好,但是你如何向暂停的浏览器发送请求然后启动它们?
我找到了requestIdleCallback()但同样,如果我已经在网站上有一个心跳计时器,我认为这不是我想要的。它也不适用于所有浏览器。
我对如何做到这一点非常迷茫,我可以举的例子是:
登录您的银行,让您的计算机进入睡眠状态,等待 15-20 分钟,唤醒计算机,登录并看到您的银行现在在登录屏幕上显示您。这就是我想要的。但我不知道如何做到这一点。
您无法从后端向“休眠”浏览器发送事件,虽然这必须是后端解决方案,但您如何更新前端,以便它们在重新唤醒笔记本电脑时显示在注销屏幕上还是电脑?
更新
关于 WebSocket 请求,我假设您正在使用Laravel WebSockets和pusher. Pusher.io 不支持超时,您可以阅读这篇支持文章“您计划向 Channels Pusher-js 客户端库添加连接超时功能吗?” 。如果启用 Laravel 调试模式(APP_DEBUG=true 内部 .env)并laravel-websockets从终端(php artisan websockets:serve)开始,您可以对其进行测试,这样您就可以看到输出日志事件。如果您尝试关闭笔记本电脑盖或将计算机设置为休眠模式 ( sleep ),您将看不到有关此事件的任何消息。你不能用pusher协议来做到这一点。有Presence 事件,但仅当您关闭选项卡或注销时才会触发。当然,您可以将客户端自定义事件触发到存在通道,但要做到这一点,您还需要在客户端设置一个计时器,并且您必须为服务器创建一个服务提供者,就像这个 github 问题“Exist a way to实施网络钩子吗?” 。member_removed laravel-websockets
有些人在其他类似问题中建议:
...
- 让计时器在前端运行(我们这样做,当你合上笔记本电脑盖子时它就会停止)
发生这种情况是因为客户端计时器在休眠时停止执行,因此它们从之前的位置继续执行。但是,如果您使用日期变量来保存时间,当计算机进入休眠状态时,该变量将不会更新,因此您可以通过检查该日期变量来知道它何时从睡眠中退出,该日期变量与当前时间相比将有显着的变化差值将大于计时器间隔。
您还可以查看此相关 Q/A 的实现:Can any Desktop browsers detector when the computer returns from sleep?
您可以在客户端中设置一个计时器每分钟运行一次。我们不会依赖计时器间隔,而是如果自上次计时器以来的时间跨度大于分钟,则计时器将检查外部范围日期变量15;如果是,则意味着浏览器/JS 由于某种原因停止执行,可能是设备休眠(sleep ),然后您将用户重定向到注销路由。
// 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);
Run Code Online (Sandbox Code Playgroud)
您可以在此处检查这个简单的示例,但使用带有秒注销的。1第二个计时器15最好在笔记本电脑上进行测试,合上盖子, 15 秒后再次打开每两分钟
您甚至可以使用Web Workers API来设置更安全的 Web Worker:
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
}
}
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
您还可以在此处检查具有相同15秒计时器的 Web Worker 示例。