阅读 1337

浏览器关闭之后清除token

系统在关闭之后再次打开,如果此时的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());
        };
复制代码

终极方案

localStorage替换成sessionStorage来存储token,可以完美实现关闭浏览器后清除token的效果。

因为sessionStorage不是一种持久化的本地存储,仅是会话级别的存储。而localStorage是持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。

当然并不是所有情况下都使用sessionStorage代替localStorage。

如果需要窗口关闭之后一段时间内还可以直接进入系统,就使用localStorage存储token。

如果需要窗口关闭之后不能直接进入系统,而需要输入密码,则使用sessionStorage。

最后,感谢评论区的指正,奥里给!!!

文章分类
前端
文章标签