多个选项卡同一个会话,当所有选项卡都消失时清除会话
Multiple tabs same session, clear the session when all tabs are gone
所以我最近对我正在构建的网站有这样的验收标准:
- 用户在任何选项卡中登录站点后,如果他们在新选项卡中导航到站点,则他们必须已经登录
- 当用户退出任何选项卡时,他们必须立即退出所有选项卡
- 用户可以刷新页面并保持登录状态
- 关闭所有选项卡后,用户将注销并且必须重新登录
- 我无权更改服务器代码(因此必须在客户端上完成)
我发现这个 真的很有帮助
查看此内容时,我不得不排除 cookie,因为除了向服务器选项卡 A 发出请求之外,将不知道选项卡 B 更改了 cookie
所以我从上面的问题中提取了部分答案并开始使用本地存储并添加了一个事件来检查 'logged-in' 状态是否已更改,这允许我在一个选项卡中注销并立即在另一个注销而不使用 setInterval 连续检查!耶
但是如果您打开一个新选项卡并导航到您仍然登录的站点,我仍然会遇到所有选项卡关闭后的问题。
我尝试了一些可能的解决方案,例如在选项卡 close/open(使用 window.onbeforeunload)上设置会话打开、递减和递增的选项卡计数器。问题:当只有一个选项卡处于活动状态时刷新站点会使您注销。我能想到的所有东西都有一个不起作用的边缘案例。
本地存储 + 会话存储!
我会将登录的值存储在本地存储和会话存储中,当加载 window 时(新选项卡或现有选项卡的刷新)它会检查本地-'logged-in' 值的存储,如果不存在,它将检查会话存储!
基本上,我使用会话存储来处理页面刷新,使用本地存储来处理多个选项卡。每次 window/tab 被卸载(关闭或刷新)我删除本地存储 'logged-in' 并且当我返回页面时如果它在会话存储但不在本地存储我把它从会话存储返回到本地存储并以经过身份验证的用户身份继续
这里是代码:
登录时:
localStorage.setItem('logged-in', true);
sessionStorage.setItem('logged-in', true);
在我的基础组件中:
window.onbeforeunload = (event) => {
localStorage.removeItem('logged-in');
}
let loggedIn = localStorage.getItem('logged-in');
let sessionLoggedIn = sessionStorage.getItem('logged-in');
if(!loggedIn) {
if(sessionLoggedIn) {
localStorage.setItem('logged-in', JSON.parse(sessionLoggedIn));
//go to authenticated space
window.location.href = '/authenticated';
} else {
//go to login
window.location.href = '/login';
}
} else {
//go to authenticated space
window.location.href = '/authenticated';
}
window.addEventListener('storage', (event) => {
if (event.key == 'logout' && event.newValue) {
sessionStorage.removeItem('logged-in');
localStorage.removeItem('logout');
window.location.href = '/login';
}
});
注销时
localStorage.setItem('logout', true)
如果您发现自己处于类似情况,希望这对您有所帮助
所以我最近对我正在构建的网站有这样的验收标准:
- 用户在任何选项卡中登录站点后,如果他们在新选项卡中导航到站点,则他们必须已经登录
- 当用户退出任何选项卡时,他们必须立即退出所有选项卡
- 用户可以刷新页面并保持登录状态
- 关闭所有选项卡后,用户将注销并且必须重新登录
- 我无权更改服务器代码(因此必须在客户端上完成)
我发现这个
查看此内容时,我不得不排除 cookie,因为除了向服务器选项卡 A 发出请求之外,将不知道选项卡 B 更改了 cookie
所以我从上面的问题中提取了部分答案并开始使用本地存储并添加了一个事件来检查 'logged-in' 状态是否已更改,这允许我在一个选项卡中注销并立即在另一个注销而不使用 setInterval 连续检查!耶
但是如果您打开一个新选项卡并导航到您仍然登录的站点,我仍然会遇到所有选项卡关闭后的问题。
我尝试了一些可能的解决方案,例如在选项卡 close/open(使用 window.onbeforeunload)上设置会话打开、递减和递增的选项卡计数器。问题:当只有一个选项卡处于活动状态时刷新站点会使您注销。我能想到的所有东西都有一个不起作用的边缘案例。
本地存储 + 会话存储!
我会将登录的值存储在本地存储和会话存储中,当加载 window 时(新选项卡或现有选项卡的刷新)它会检查本地-'logged-in' 值的存储,如果不存在,它将检查会话存储!
基本上,我使用会话存储来处理页面刷新,使用本地存储来处理多个选项卡。每次 window/tab 被卸载(关闭或刷新)我删除本地存储 'logged-in' 并且当我返回页面时如果它在会话存储但不在本地存储我把它从会话存储返回到本地存储并以经过身份验证的用户身份继续
这里是代码:
登录时:
localStorage.setItem('logged-in', true);
sessionStorage.setItem('logged-in', true);
在我的基础组件中:
window.onbeforeunload = (event) => {
localStorage.removeItem('logged-in');
}
let loggedIn = localStorage.getItem('logged-in');
let sessionLoggedIn = sessionStorage.getItem('logged-in');
if(!loggedIn) {
if(sessionLoggedIn) {
localStorage.setItem('logged-in', JSON.parse(sessionLoggedIn));
//go to authenticated space
window.location.href = '/authenticated';
} else {
//go to login
window.location.href = '/login';
}
} else {
//go to authenticated space
window.location.href = '/authenticated';
}
window.addEventListener('storage', (event) => {
if (event.key == 'logout' && event.newValue) {
sessionStorage.removeItem('logged-in');
localStorage.removeItem('logout');
window.location.href = '/login';
}
});
注销时
localStorage.setItem('logout', true)
如果您发现自己处于类似情况,希望这对您有所帮助