浏览器及标签页关闭时登出的解决方案

一、前言

项目出于安全评测的要求,需要页面在浏览器及其标签页关闭的时候登出,保证每次进入系统都重新登录。 核心处理逻辑有如下几点:

  1. 监听浏览器关闭事件
  2. 关闭时清除本地存储的token
  3. 关闭时调用登出接口保证后端redis中token被清除

通过AI和网络搜索 给出的方案,很快就实现了。但在自测验证过程中,发现有两个费劲周折的问题。

  1. beforeunload 事件在页面刷新时也会触发,而排除是刷新的情况 试了N种方案都不尽人意
  2. 标签页关闭后axios触发的登出请求 会被浏览器取消,后端接收不到。

折腾一波后,最终都解决了,这里记录下解决方案。

二、解决方案

2.1 标签页关闭时登出,但排除刷新的场景

unload事件中增加刷新情况的判断。除了下面代码中时间差的判断方法外,还尝试过performance.navigation等方案,都无效。

javascript 复制代码
let _beforeUnload_time = 0
let _gap_time = 0
window.onbeforeunload = () => {
  _beforeUnload_time = new Date().getTime();
  console.log("beforeUnload_time", _beforeUnload_time);
};

window.onunload = (event) => {
  _gap_time = new Date().getTime() - _beforeUnload_time;
  console.log("gap_time", _gap_time);
if (_gap_time <= 5 || event.altKey) {
    // 执行关闭需要进行的操作,1. 清除本地缓存;2. 发送登出接口
    console.log("xxxxxxx关闭");
  }else{
    console.log("页面刷新");
  }
};

2.2 登出请求,避免被浏览器取消

Fetch的keepalive可以在页面卸载(如用户关闭标签页或跳转到新页面)后,确保请求仍能在后台完成的选项

php 复制代码
fetch('/api/logout', {
  method: 'GET',
  headers: {
    'Authorization': token
  },
  keepalive: true, // 类似 sendBeacon 的行为
});

2.3 浏览器关闭再进入的场景

基于sessionStorage做判断,存储在 sessionStorage 里面的数据在页面会话结束时会被浏览器自动清除。

arduino 复制代码
// 初次进入跳转登录页面
if (!sessionStorage.getItem("entered")) {
  location.hash = "#/login";
  sessionStorage.setItem("entered", "true");
}

三、参考资料

相关推荐
m0_7482299911 分钟前
Vue2 vs Vue3:核心差异全解析
前端·javascript·vue.js
C澒32 分钟前
前端监控系统的最佳实践
前端·安全·运维开发
xiaoxue..35 分钟前
React 手写实现的 KeepAlive 组件
前端·javascript·react.js·面试
hhy_smile41 分钟前
Class in Python
java·前端·python
小邓吖1 小时前
自己做了一个工具网站
前端·分布式·后端·中间件·架构·golang
南风知我意9571 小时前
【前端面试2】基础面试(杂项)
前端·面试·职场和发展
LJianK12 小时前
BUG: Uncaught Error: [DecimalError] Invalid argument: .0
前端
No Silver Bullet2 小时前
Nginx 内存不足对Web 应用的影响分析
运维·前端·nginx
一起养小猫2 小时前
Flutter for OpenHarmony 实战 表单处理与验证完整指南
android·开发语言·前端·javascript·flutter·harmonyos
weixin_395448912 小时前
main.c_cursor_0130
前端·网络·算法