登录问题、前端区分刷新和关闭页面

用户的需求:

1. 页面多开的情况下,登录状态必须一致

2. 当处于登录状态时,但页面处于登录页,要求刷新之后从login跳转到首页,并且登陆状态不允许直接跳转到login页面

3. 当token无效时,调用任意接口直接退出登录

4. 页面关闭自动退出登录

思路:

1. 由于第一点,所以必须使用localstorage 如果使用sessionStorage或者cookie无法保证新开的页面也存储了token参考(sessionStorage在不同页签中的数据是否共享问题及解决思路_sessionstorage 不同标签_道长道长IOT的博客-CSDN博客

2. 使用路由守卫

  • 首先判断是否有token,若没有直接跳转到页面
  • 其次判断token是否有效,若有效,且访问的是/  或/login 则next到首页
  • 若token无效则跳转到/login页(此时清空掉现有的无效token最好,不清除也可以)
    router.beforeEach(async (to, from, next) => {
      // 存储上个地址 用于返回按钮(直接使用back 会导致在新标签页打开时返回到新建标签页)
      store.commit('control/setPreRoute', from)
      if (localStorage.getItem('token')) {
        if (!store.state.user.menu.length) { // 解决首次刷新路由没有添加的问题
          // token是否有效
          try {
            await store.dispatch('user/fetchUserProfile')
            //token有效
            // 获取到路由之后 才添加
            await store.dispatch('user/fetchMenu')
            if (['/','/login'].includes(to.path)) {
              next('/dashboard')
            } else {
              next({ ...to, reolace: true })
            }
          } catch (e) {
            // token无效
            ElMessage({
              message: e,
              type: "error",
            });
            next('/login')
          }
        } else {
          next()
        }
      } else {
        next()
      }
    })

    3. 在axios响应拦截器中,配置如果响应401且当前不在login页 就调用登出方法(跳到login并清除token)

  • instance.interceptors.response.use((res) => {
      let { status, data,headers } = res
      if (status >= 200 && status < 300) {
        if(headers['x-pagination']){
          return {
            data,
            pagination:JSON.parse(headers['x-pagination'])
          }
        }else{
          return data;
        }
      }
      else {
        return Promise.reject(data);
      }
    }, err => {
      if((err.response.status === 401) && ( router.currentRoute.value.name !='login')){
        ElMessage({
          message: '登录过期,请重新登陆',
          type: 'warning'
        })
        store.commit('user/logout')
      }
      return Promise.reject(err);
    });

    4. 由于是使用localStorage,在浏览器关闭页面后存储在localStorage中的token并不会消失,所以一开始想到了在App销毁时清除localStorage,但此时会造成已登录的用户在刷新页面后跳转到登录页面的问题,所以不能直接采用这种方法,需要前端想办法区分用户的关闭和刷新操作。

  • 参考链接vue实现在用户关闭或刷新浏览器当前网页时弹出提示“系统可能不会保存您所做的更改”

理解:当用户直接关闭浏览器时 beforeunload 与unload时间间隔是很短的,但如果刷新两者时间间隔会很长(尤其是在beforeunload 加了以下代码后:会唤醒一个弹窗)

    e.preventDefault();
    e.returnValue = "";

到此,上述的四个要求基本满足,但仍存在一个问题,当我直接在浏览器地址栏输入其它非自己项目的地址(如 百度...之类的),此时再跳转回来,仍然是已登录状态,与用户希望离开此页面就取消登录相违背。希望能收到大家的解决方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值