点赞
评论
收藏
分享
举报
看完怒涨薪资30k?同一浏览器只允许登录一个账号的解决办法(Vue单页)
发表于2021-12-13 15:56

浏览 4.3k

文章标签

相同浏览器只允许登录一个账号的需求相信是很多前端小伙伴的面临过或者将要面临的问题,看似没有什么大问题的问题,其实有点东西的。这里介绍一下我尝试多种办法之后得出的一个最优的解决办法


情况一

当窗口一登录了admin账号,再去复制项目里面的地址用窗口二打开

注意这里是项目里面的地址,有点东西的地方在于登录地址,下面再介绍,且看: 窗口二打开任意一个项目里面的地址我们要的效果都是可以直接访问的(各大bat的产品也是这样的效果,毋庸置疑)。那么我们是怎么做到当窗口一登录了之后,其他窗口可以访问项目里面的任意地址,而当没有窗口登录,复制项目里面的地址不能访问(安全问题)让其跳转到登录页 上代码:我们在main.js里面


router.beforeEach((to,from,next) => { //这里是在所有路由跳转之前都会去执行以下操作
  if(to.path == '/'){ //如果要去的是登录页
    next() //那么随意,去就是了
  } else { //如果不是
    if(localStorage.getItem('isLogin')){ //判断当前浏览器的本地存储里面是不是有已经登录的信息
      next() //有的话,ok,去你想去的地址
    } else { //没有的话,也就是没有登录
      next({path:'/'}) //去登录页
    }
  }
})
复制代码


这里的isLogin是我自己命名在login.vue的登录的时候存进去本地的,当然也可以存接口返回的user信息,whatever you like


// 登录按钮执行登录的时候,至于为什么存localStorage,不用sessionStore,自行百度其中的区别,相信你会明了的
localStorage.setItem("isLogin", 1)
复制代码


这里要注意,在退出按钮的时候要执行清除登录状态的操作,否则本地存储会一直保留(不手动清缓存的情况下)


// 执行退出登录操作的时候执行
localStorage.removeItem("isLogin")
复制代码


到这里应该都没有什么问题,都是常规操作 >o<!


情况二

当窗口二去到登录页面,并且登录了另一个非admin的账号

这种情况下,我们是不是要把窗口一的admin的账号覆盖掉?是的,可能菜单权限不一样,页面风格都不一样的情况下,我们怎么去覆盖这个页面所展示的信息?
刚开始我的想法是监听浏览器的窗口切换,再次切回窗口一的时候再次点击页面上的某处去执行接口请求的时候刷新页面,这是有逻辑上的问题的,因为我们并不能检测到页面是否有接口请求,只能接测到是否有路由跳转,但是页面上只有一部分比如菜单点击才有路由跳转,所以这个方法是有问题的。(这段废话是为了更好的表明我的思路emmmm......)


换种思路!要实现这个逻辑,我们就必须要检测到浏览器是否有新窗口执行了账号登录,也就是监测浏览器的本地存储是否有东西,vue的watch监测并不能监测非vue机制存放的数据(这句话我在上一篇文章中也提过),也就是说watch不能实时监测localStorage里面的数据,而我们或许会想到把localStorage里面的数据在保存到vuex里面去达到实时监测的效果,但是,vuex会在其他窗口登录的时候被重置,但是这个思路是对的!!!直接说我怎么实现的:


手动去创建一个js文佳再在里面创建一个全局变量export出去,把这个全局变量创建在一个单独的文件中,然后再去组件里面引用,这个全局变量是能被watch监测


要做到这个全局变量不被其他窗口的登录给重置掉,这里就是个小心思了


在登陆组件login.vue里面引入这个全局变量,在登陆按钮执行成功的时候去赋值,主要看带注释的地方


// login.vue先引入
import global from '@/config/common.js'
methods: {
  login () {
    if (this.user == '') {
          this.$message.error('账号不能为空!');
        } else if (this.password == '') {
          this.$message.error('密码不能为空!');
        } else {
          this.setCookie(this.user)
          this.$post('/api/manage/user/login.json', {
            userName: this.user,
            passWord: this.$md5(this.password)
          }).then(res => {
              localStorage.setItem("isLogin", 1)
              global.aaa = res.obj.id //这里才是登录成功的时候去赋值,我是创建的 aaa 这个变量为例子
              localStorage.setItem('userId', res.obj.id) // 同时也要做的是将这个用户id存进localStorage
              this.$router.push({path: '/container'})
            })
            .catch(err => {
              this.$message.error(err.msg)
            })
        }
      }
  }
复制代码


那我们登录成功之后会在本地代码里面保存这个用户id,也在浏览器的localStorage里面保存了一份,接着,在main.js里面


import global from '@/config/common.js'


window.addEventListener("visibilitychange",function(){ //这个方法是监测浏览器窗口发生变化的时候执行
  if (document.hidden == false && global.aaa != localStorage.getItem('userId')) {
    global.aaa = localStorage.getItem('userId') //只有当初始创建的aaa不等于localStorage里面的userId的时候去覆盖掉这个aaa
  }
  //不覆盖的话aaa永远都是我们设的初始值
});
复制代码


最后,我们在app.vue里面去监听这个全局变量的变化


watch: {
    'global.aaa' : 'refresh'
  },
methods: {
   refresh () {
  //执行刷新操作,这里我没有写this.$route.go(0),因为整个页面抖动不是很友好
  //现将app.vue下面的 头部组件,菜单组件,内容组件隐藏再放出来,实现刷新一样的效果
        this.hackReset = false
        this.$nextTick(() => {
          this.hackReset = true
        })
      }
}
复制代码


好了,在第二个窗口登录另一个账号,返回第一个窗口的时候,改窗口登了的账号被挤掉,整个页面同步到第二个窗口所登录的账号信息,这个效果实现了!!!代码倒是没有什么很高深的要写,只是思路很重要,有点曲折,实现完功能发现,头发又掉了好几根。


结束语

本文提供作者:蜗牛先笙
原贴地址:www.jianshu.com/p/89b0c29cb…
觉得文章写的好,请给戳↑链接关注作者,给文章点个赞嗷~
摸鱼学习交流请戳:shimo.im/sheets/CtcH…

已修改于2023-03-09 02:20
创作不易,留下一份鼓励
好文分享者

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
好文分享者
这家伙很懒还未留下介绍~
2
文章
0
问答
1
粉丝
相关文章
前言大家平时在工作中,或多或少应该接触过微信鉴权登录,获取用户信息的相关需求。也有小伙伴经常会在群里问一些相关的问题,比如鉴权登录的整体流程是什么?整个流程里面,前端和后端的分工是什么?前端专门准备了一个鉴权回调页面,要怎么回到鉴权前的页面?怎么在本地测试微信网页授权?先看看微信官方的鉴权流程怎么描述的第一步:用户同意授权,获取code第二步:通过code换取网页授权access_token第三步:刷新access_token(如果需要)第四步:拉取用户信息(需scope为snsapi_userinfo)还是懵,没关系,我在这里专门准备了一个小🌰,来实现了一套简易版的网页授权+获取用户信息的功能,整个流程大概是这样的在这个流程中,前端不用做太多事,只需要判断有没有用户信息,如果没有,剩下的事情交给服务端,等服务端全部处理完成,会带着用户信息,返回之前的页面。并且前端无需准备专门的授权结果页。流程第一步:内网映射下载软件下载地址:ngrok.com/download解压出来之后是这个东西终端启动将解压出来的文件拖到终端中,紧接着写http3000,意思就是用ngrok在3000端口上
点赞 0
浏览 4.1k
原文作者:ElijahZupancicofF5和 JasonSchmidtofF5原文链接:现代应用参考架构之OpenTelemetry集成进展报告 -NGINX转载来源:NGINX官方网站  去年秋天我们在Sprint2.0上介绍NGINX现代应用参考架构 (MARA)项目时,就曾强调过这不是一个随随便便的架构,我们的初衷是打造一款“稳定可靠、经过测试且可以部署到在Kubernetes环境中运行的实时生产应用”的解决方案。对于这样一个项目来说,可观测性工具可以说是必不可少。MARA团队的所有成员都曾亲身体验过,缺乏状态和性能洞察会让应用开发和交付变得多么困难。我们很快就达成了共识,即MARA必须添加可以在生产环境中进行调试和跟踪的工具。MARA的另一项指导原则是首选开源解决方案。本文描述了我们对多功能开源可观测性工具的追求是如何使我们将目光转向 OpenTelemetry 的,然后详细介绍了其中的利弊权衡和设计决策,以及采用了哪些技术将OpenTelemetry与使
点赞 1
浏览 5.3k
原文作者:陶辉原文链接:课程实录 | Ingress Controller 的工作原理(上)转载来源:NGINX 开源社区NGINX 唯一中文官方社区 ,尽在nginx.org.cn编者按——本文为系
点赞 1
浏览 4.2k