用同一个浏览器登录一个账号A之后,再打开一个新的tab标签页重新登录一个不同于账号A角色权限的账号B之后,浏览器中A的token被B覆盖,导致A账号提交数据时候可能会出现后台误以为是B账号进行的一些操作,从而导致后台数据保存出现匹配错误的bug;

原文链接

一、一个浏览器同时只能允许一个账号的在线

①vue中新建一个全局变量用来保存当前用户token
新建一个constants.js文件

/**
 * 全局变量定义
 */
export let global = {
    "token": ''
}

把token保存到localstorage的同时也保存一份到当前vue的全局变量中

import {global} from '@/utils/constant'
global.token = res.data.token // 赋值给全局变量

②App.vue中

mounted() {
      document.addEventListener('visibilitychange', this.checkNameExpired);
    },
    beforeDestroy() {
      document.removeEventListener('visibilitychange', this.checkNameExpired);
    },
    methods: {
      checkNameExpired() {
        console.log(global.token)
        if (document.hidden == false && global.token != getToken()) {
          global.token= getToken() //当前登录的用户信息与全局存的用户信息不同,覆盖新的用户信息,否则是最初设的值
          // 这里样式可以根据项目优化,刷新页面
          window.location.reload();
        }
      }
    }

使用场景:有三种存登录cookies的方法Cookie、LocalStorage和SessionStorage,这里使用的是VueCookies.get('xxx')且在浏览器中设置过期时间;
App.vue

<template>
  <router-view/>
</template>

<script>
  import globalData from "@/util/globalData";
  import VueCookies from "vue-cookies";

  export default {
    data(){
      return{

      }
    },
    mounted() {
    //如果不加这个判断条件,点开窗口它就要刷新一次;
    //此时它实现了:其中一个窗口登录退出换新账号,第二三四五等个窗口自动刷新登录退出换新账号;
    if(VueCookies.get('xxx') !== null){
        if (globalData.myToken=== null){
          globalData.myToken= VueCookies.get('xxx')
        }
      }
      document.addEventListener('visibilitychange', this.checkNameExpired);
    },
    beforeDestroy() {
      document.removeEventListener('visibilitychange', this.checkNameExpired);
    },
    methods: {
      checkNameExpired() {
        if (document.hidden === false && globalData.myToken!== VueCookies.get('xxx')) {
          globalData.myToken= VueCookies.get('xxx') //当前登录的用户信息与全局存的用户信息不同,覆盖新的用户信息,否则是最初设的值
          // 这里样式可以根据项目优化,刷新页面
          window.location.reload();
        }
      }
    }
  }
</script>

创建globalData.js存放全局变量token值;

let obj = {
   myToken: ''
}

export default obj

登录时候存登录信息;

	if (res.obj.info === "登录成功") {
	globalData.myToken= res.obj.token;
          let loginInfo = {
            hhh: res.obj.userId,
            username: this.loginForm.username,
            aaa: res.obj.isManager,
            token: res.obj.token,
            time: res.obj.time
          }
          this.$store.commit("login", loginInfo);
          // this.$cookies.set("isManager", loginInfo.isManager);
          if (loginInfo.isManager === true) {
            this.$router.push("/a");
          } else {
            this.$router.push("/b");
          }
          this.getUserInfoById(this.$store.getters.hhh);
          //如果勾选记住密码
          if (this.remember === true) {
            this.$cookies.set("username", this.loginForm.username, 3 * 24 * 60 * 60);
            this.$cookies.set("password", Base64.encode(this.loginForm.password), 3 * 24 * 60 * 60);
          } else {
            // 否则移除
            this.$cookies.remove('username');
            this.$cookies.remove('password');
          }
          return;
        }

使用vuex来管理用户信息;

import { createStore } from 'vuex'
import VueCookies from 'vue-cookies'
import globalData from "../util/globalData";
import appGlobal from "@/store/modules/appGlobal";

export default createStore({
  state: {
    //驱动应用的数据源
    userId: '' || VueCookies.get('hhh'),
    isManager:VueCookies.get('aaa'),
  },
  getters: {
    userId: (state) => state.userId,
    isManager: (state) => state.isManager
  },
  mutations: {
    login: (state, loginInfo) => {
      VueCookies.remove("hhh");
      VueCookies.remove("xxx");
      VueCookies.remove("aaa");
      state.userId = loginInfo.userId;
      state.isManager = loginInfo.isManager;
      // 把登录的用户的名保存到localStorage中,防止页面刷新,导致vuex重新启动,用户名就成为初始值(初始值为空)的情况
      VueCookies.set("hhh",loginInfo.userId,loginInfo.time/1000);
      VueCookies.set("xxx",loginInfo.token,loginInfo.time/1000);
      VueCookies.set("aaa",loginInfo.isManager,loginInfo.time/1000);
    },
    setManager(state, isManager){
      state.isManager = isManager;
    },
    logout:(state) =>{
      state.userId = null;
      state.isManager = false;
      VueCookies.remove('hhh');
      VueCookies.remove("xxx");
      VueCookies.remove("aaa");
    }

  },
  actions: {
  },
  modules: {
    /**
     * app全局参数
     */
    appGlobal,
  }
})

二、vue项目中实现同一个浏览器登录多个用户账号

让不同的用户存储的token的键名不一样;在登录的时候存储用TOKEN+userName作为键来存储token;

import Cookies from 'js-cookie'
import Config from '@/config'
const TokenKey = Config.TokenKey;

export function getToken() {
  return Cookies.get( TokenKey + sessionStorage.getItem( 'username' ) )
}

export function setToken( token, rememberMe, username ) {
  if ( rememberMe ) {
    return Cookies.set( TokenKey + username, token, { expires: Config.tokenCookieExpires } )
  } else {
    return Cookies.set( TokenKey + username, token )
  }
}

export function removeToken( username ) {
  return Cookies.remove( TokenKey + username )
}

页面刷新前存储用户名

    window.addEventListener("beforeunload", () => {
      sessionStorage.setItem("username", this.user.username || "");
    });

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐