系统在关闭之后再次打开,如果此时的token没有过期的话,用户无需登录就可以进入主页。
但是***觉得这其中存在着安全隐患。假设有这么一个场景,老师登录成绩管理系统,给你高数打了35分,那么你可以在老师关闭浏览器离开之后快速打开系统,重新修改为99分。
妙啊ヾ(≧▽≦*)o
那么如何能够残忍避免“学生改成绩”这一行为呢?
知识点
浏览器关闭会触发beforeunload , unload 页面卸载这两个事件。
而实践之后发现浏览器刷新也会触发beforeunload , unload 这两个事件,此外还会触发load页面加载事件。
实践
- 方案一:
在beforeunload中直接清除token。
源码:
window.onbeforeunload = function () {
localStorage.removeItem("token");
};
复制代码
我关闭浏览器再打开需要登录,一开始我以为成功了,可是刷新浏览器之后发现也需要登录,哦豁,宣告失败(真是头秃。。。)。
- 方案二:
在浏览器触发onbeforeunload的时候创建一个时间,在触发onunload事件的时候再创建另一个时间,两个时间相减,如果时间间隔很小则为关闭,否则为刷新。
源码:
let beginTime = 0; //开始时间
let differTime = 0; //时间差
const interval = 5; //时间间隔 - 5ms
window.onunload = function () {
differTime = new Date().getTime() - beginTime;
if (differTime <= interval) {
localStorage.removeItem("token");
} else {
console.log("这是刷新");
}
};
window.onbeforeunload = function () {
beginTime = new Date().getTime();
};
复制代码
实践之后发现刷新的问题也解决了,欣喜若狂,赶快提交代码。可是项目发布之后,在同事电脑浏览器执行刷新的时候会偶尔出现需要重新的情况。。(再次难受了)
具体原因是:设置的interval这个时间间隔在不同的电脑上存在差异,导致无法准确地判断当前行为是刷新还是关闭标签页,所以这个方案也存在着问题。
- 方案三
在浏览器触发onunload事件的时候使用localStorage保存一个当前时间,在浏览器触发onload读取保存的时间,再创建一个新的时间,如果时间间隔大于3s,则清除token。这种和第二种的不同之处是这种大幅度延长了检测的interval,并且把这个清除token的操作从页面卸载转移到了页面装载。
源码:
window.onload = function () {
let lastTime = localStorage.getItem("lastTime");
const interval = 3 * 1000;
// 如果没有上一次离开的时间或者时间间隔大于3s,就清除token
if (!lastTime || new Date().getTime() - lastTime > interval) {
localStorage.removeItem("token");
console.log("清除token")
}else{
console.log("时间过短不清除token")
}
};
window.onunload = function () {
localStorage.setItem("lastTime", new Date().getTime());
};
复制代码
目前我是采用的方案三作为最后的解决办法。欢迎在评论区给出您的解决方案。