深入探索 window.addEventListener(‘storage’) 事件

接下来分享关于 storage 原生api 应用的场景:

当我们在同一浏览器,不同的标签页,登录账号的时候

深入探索 window.addEventListener('storage') 事件

先登录子账号的token

深入探索 window.addEventListener('storage') 事件

然后再登录主账号的token

深入探索 window.addEventListener('storage') 事件

重点来了,这时候我们在返回登录子账号的标签页发现:

深入探索 window.addEventListener('storage') 事件

原有子账号的token被主账号的token给覆盖了。

这时候就会有同学发现,我们token是存到了localStorage里面。~没错

所以localStorage很重要的一点是这样的

深入探索 window.addEventListener('storage') 事件

所以我们就能理解,为什么token会覆盖的问题了。

那么会有什么问题呢?

栗子:如果我们当前的系统涉及到权限的话,按照上面的处理就会出现越权,大白话说就是我们登录子账号,后续再登录主账号时,原本子账号的token在localStorage的机制下,被主账号的token覆盖了,那么我们现在在子账号的标签页下,携带主账号的token请求数据,是不是就越权了。

这是我们今天要解决的问题了,直接说解决方案:

window.addEventListener(‘storage’) 是在Web开发中用于监听浏览器全局 localStorage 或 sessionStorage 改变的事件监听器。当一个窗口(window)或标签页中的数据存储发生变化时,该事件会在所有同源的窗口和标签页中触发。

事件处理器函数接收一个 StorageEvent 对象作为参数,该对象包含以下属性:

  • key:发生变化的存储项的键名。
  • oldValue:存储项更改前的旧值。
  • newValue:存储项更改后的最新值。
  • url:触发 storage 事件的文档的URL。
  • storageArea:引用到发生改变的存储区对象,可能是 localStorage 或 sessionStorage。
window.addEventListener('storage', function(event) {
2  console.log('A storage change occurred:');
3  console.log('Key: ', event.key);
4  console.log('Old Value: ', event.oldValue);
5  console.log('New Value: ', event.newValue);
6  console.log('Originated from: ', event.url);
7});
8
9// 在其他窗口或标签页中修改localStorage
10localStorage.setItem('myKey', 'new value');

当任何同源窗口或标签页中 localStorage 的 myKey 键值发生变化时,该事件监听器就会触发,并输出相关信息.

注意,sessionStorage 的变化不会触发此事件,因为 sessionStorage 的数据是独立于每个窗口或标签页的。

一,在登录接口,通过localStorage存储

login({
    commit
  }, userInfo) {
    return new Promise((resolve, reject) => {
    //接口请求
      login(userInfo).then(response => {
        const {
          data
        } = response
        if (data.token) {
         //关键代码
          localStorage.setItem('UPDATE', 'refreshOtherPage')
        }
        resolve(response)
      }).catch(error => {
        console.log('error :', error)
        reject(error)
      })
    })
  },

二.我们在main.js中

window.addEventListener('storage', function(e) {
  if (e.key === 'UPDATE' && e.newValue === 'refreshOtherPage') {
    //do something
    //可以请求 userInfo的接口
    setTimeout(() => location.reload(), 17) // 刷新首页
  }
})

三.退出登录的时候删掉

localStorage.removeItem('UPDATE')

这是效果,在后续的标签页重新登陆的话就会触发之前标签页中main.js中的代码,去刷新页面或者请求接口,,相当于利用被覆盖的token,请求用户信息的接口,接口会根据token,查询当前用户的信息,就会把当前子账号的改成主账号。这样那个就不会存在越权的问题了,因为我们把账号变成了同一个账号。

深入探索 window.addEventListener('storage') 事件

我们项目中如果token存到localStorage中,并且会有权限的功能,那就需要根据以上的描述并结合自己的项目会不会存在这种情况的发生。

原文链接:https://juejin.cn/post/7351712561672650804 作者:取名真的好难

(0)
上一篇 2024年3月31日 上午10:59
下一篇 2024年3月31日 上午11:10

相关推荐

发表评论

登录后才能评论