Prechádzať zdrojové kódy

fix: multi windows token sharing

修复同时打开多个窗口时令牌没能同步共享的问题

fixed: #761
无木 3 rokov pred
rodič
commit
e5f37885ff

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -12,6 +12,7 @@
 - **Table** 修复为 table 提供 rowSelection.onChange 时,无法手动变更 table 的选中项的问题
 - **Icon** 修复 SvgIcon 缺少部分样式的问题
 - **LockScreen** 修复锁屏功能可以通过刷新页面或复制 URL 打开新的浏览器标签来跳过锁定状态的问题
+- 修复多个窗口同时打开页面时,`Token` 不会同步的问题
 
 ## 2.5.2(2021-06-27)
 

+ 14 - 0
mock/sys/user.ts

@@ -95,4 +95,18 @@ export default [
       return resultSuccess(codeList);
     },
   },
+  {
+    url: '/basic-api/logout',
+    timeout: 200,
+    method: 'get',
+    response: (request: requestParams) => {
+      const token = getRequestToken(request);
+      if (!token) return resultError('Invalid token');
+      const checkUser = createFakeUserList().find((item) => item.token === token);
+      if (!checkUser) {
+        return resultError('Invalid token!');
+      }
+      return resultSuccess(undefined, { message: 'Token has been destroyed' });
+    },
+  },
 ] as MockMethod[];

+ 5 - 0
src/api/sys/user.ts

@@ -5,6 +5,7 @@ import { ErrorMessageMode } from '/#/axios';
 
 enum Api {
   Login = '/login',
+  Logout = '/logout',
   GetUserInfo = '/getUserInfo',
   GetPermCode = '/getPermCode',
 }
@@ -34,3 +35,7 @@ export function getUserInfo() {
 export function getPermCode() {
   return defHttp.get<string[]>({ url: Api.GetPermCode });
 }
+
+export function doLogout() {
+  return defHttp.get({ url: Api.Logout });
+}

+ 9 - 2
src/store/modules/user.ts

@@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum';
 import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
 import { getAuthCache, setAuthCache } from '/@/utils/auth';
 import { GetUserInfoModel, LoginParams } from '/@/api/sys/model/userModel';
-import { getUserInfo, loginApi } from '/@/api/sys/user';
+import { doLogout, getUserInfo, loginApi } from '/@/api/sys/user';
 import { useI18n } from '/@/hooks/web/useI18n';
 import { useMessage } from '/@/hooks/web/useMessage';
 import { router } from '/@/router';
@@ -105,7 +105,14 @@ export const useUserStore = defineStore({
     /**
      * @description: logout
      */
-    logout(goLogin = false) {
+    async logout(goLogin = false) {
+      try {
+        await doLogout();
+      } catch {
+        console.log('注销Token失败');
+      }
+      this.setToken(undefined);
+      this.setSessionTimeout(false);
       goLogin && router.push(PageEnum.BASE_LOGIN);
     },
 

+ 5 - 0
src/utils/auth/index.ts

@@ -19,3 +19,8 @@ export function setAuthCache(key: BasicKeys, value) {
   const fn = isLocal ? Persistent.setLocal : Persistent.setSession;
   return fn(key, value, true);
 }
+
+export function clearAuthCache(immediate = true) {
+  const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession;
+  return fn(immediate);
+}

+ 10 - 2
src/utils/cache/persistent.ts

@@ -16,6 +16,7 @@ import {
 } from '/@/enums/cacheEnum';
 import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';
 import { toRaw } from 'vue';
+import { pick } from 'lodash-es';
 
 interface BasicStore {
   [TOKEN_KEY]: string | number | null | undefined;
@@ -96,8 +97,15 @@ export class Persistent {
 }
 
 window.addEventListener('beforeunload', function () {
-  ls.set(APP_LOCAL_CACHE_KEY, localMemory.getCache);
-  ss.set(APP_SESSION_CACHE_KEY, sessionMemory.getCache);
+  // TOKEN_KEY 在登录或注销时已经写入到storage了,此处为了解决同时打开多个窗口时token不同步的问题
+  ls.set(APP_LOCAL_CACHE_KEY, {
+    ...localMemory.getCache,
+    ...pick(ls.get(APP_LOCAL_CACHE_KEY), [TOKEN_KEY, USER_INFO_KEY]),
+  });
+  ss.set(APP_SESSION_CACHE_KEY, {
+    ...sessionMemory.getCache,
+    ...pick(sessionMemory.getCache, [TOKEN_KEY, USER_INFO_KEY]),
+  });
 });
 
 function storageChange(e: any) {