From 30b219e14dbf2127b4fa16df6f007ba29fcbba8b Mon Sep 17 00:00:00 2001 From: caozehui <2427765068@qq.com> Date: Mon, 14 Apr 2025 14:43:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/index.ts | 13 ++++++ frontend/src/api/user/interface/user.ts | 1 + frontend/src/api/user/login/index.ts | 6 +-- .../components/Header/components/Avatar.vue | 2 +- frontend/src/routers/modules/dynamicRouter.ts | 2 + frontend/src/stores/modules/user.ts | 4 ++ .../src/views/login/components/LoginForm.vue | 41 ++++--------------- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index cfd1fc1..e634f4e 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -76,6 +76,7 @@ class RequestHttp { userStore.setAccessToken(result.data.accessToken) userStore.setRefreshToken(result.data.refreshToken) userStore.setIsRefreshToken(false) + userStore.setExp(1000 * 60 * 60 * 24 * 30) response.config.headers.Authorization = `Bearer ${result.data.accessToken}`//重新请求前需要将更新后的新token更换掉之前无效的token,不然会死循环 const resp = await this.service.request(response.config) return resp @@ -90,6 +91,7 @@ class RequestHttp { userStore.setRefreshToken('') userStore.setIsRefreshToken(false) userStore.setUserInfo({ id:'',name: '' }) + userStore.setExp(0) await router.replace(LOGIN_URL) if(isFirst){//临时处理token失效弹窗多次 ElMessage.error(data.message) @@ -112,6 +114,17 @@ class RequestHttp { return Promise.reject(data) } // 成功请求(在页面上除非特殊情况,否则不用处理失败逻辑) + + if (userStore.exp <= Date.now() && userStore.exp !== 0) { + userStore.setAccessToken('') + userStore.setRefreshToken('') + userStore.setIsRefreshToken(false) + userStore.setUserInfo({ id:'',name: '' }) + userStore.setExp(0) + ElMessage.error('登录已过期,请重新登录!') + await router.replace(LOGIN_URL) + return Promise.reject(data) + } return data }, async (error: AxiosError) => { diff --git a/frontend/src/api/user/interface/user.ts b/frontend/src/api/user/interface/user.ts index dd03e97..db73f46 100644 --- a/frontend/src/api/user/interface/user.ts +++ b/frontend/src/api/user/interface/user.ts @@ -11,6 +11,7 @@ export namespace Login { accessToken: string; refreshToken: string; userInfo:{ + id: string; name: string; } } diff --git a/frontend/src/api/user/login/index.ts b/frontend/src/api/user/login/index.ts index eeca626..a316ef0 100644 --- a/frontend/src/api/user/login/index.ts +++ b/frontend/src/api/user/login/index.ts @@ -7,7 +7,7 @@ import type {Dict} from '@/api/interface' * @name 登录模块 */ // 用户登录 -export const loginApi = (params: { username: string; password: string,checked: boolean }) => { +export const loginApi = (params: { username: string; password: string}) => { return http.post(`${rePrefix}/login`, params, {loading: false}) // return http.post(`/Register1`, params, { loading: false }) } @@ -47,8 +47,8 @@ export const getCurrentScene = () => { /** * 获取RSA公钥 */ -export const getPublicKey = (username: string, checked: boolean) => { - return http.get(`/admin/getPublicKey?username=${username}&checked=${checked}`, {}, {loading: false}) +export const getPublicKey = (username: string) => { + return http.get(`/admin/getPublicKey?username=${username}`, {}, {loading: false}) } /** diff --git a/frontend/src/layouts/components/Header/components/Avatar.vue b/frontend/src/layouts/components/Header/components/Avatar.vue index 1100a0a..b8a2aa9 100644 --- a/frontend/src/layouts/components/Header/components/Avatar.vue +++ b/frontend/src/layouts/components/Header/components/Avatar.vue @@ -81,7 +81,6 @@ const modeStore = useModeStore(); const AppSceneStore = useAppSceneStore(); import { useTheme } from "@/hooks/useTheme"; import { useI18n } from "vue-i18n"; -import {getPublicKey} from "@/api/user/login"; // 引入 vue-i18n 钩子 const { changePrimary} = useTheme(); // 初始化 i18n @@ -99,6 +98,7 @@ const logout = () => { // 2.清除 Token userStore.setAccessToken(""); userStore.setRefreshToken(""); + userStore.setExp(0) userStore.setUserInfo({id: "", name: ""}); userStore.setIsRefreshToken(false) dictStore.setDictData([]); diff --git a/frontend/src/routers/modules/dynamicRouter.ts b/frontend/src/routers/modules/dynamicRouter.ts index 043e2d9..cb43751 100644 --- a/frontend/src/routers/modules/dynamicRouter.ts +++ b/frontend/src/routers/modules/dynamicRouter.ts @@ -30,6 +30,7 @@ export const initDynamicRouter = async () => { }); userStore.setAccessToken(""); userStore.setRefreshToken(""); + userStore.setExp(0) router.replace(LOGIN_URL); return Promise.reject("No permission"); } @@ -52,6 +53,7 @@ export const initDynamicRouter = async () => { // 当按钮 || 菜单请求出错时,重定向到登陆页 userStore.setAccessToken(""); userStore.setRefreshToken(""); + userStore.setExp(0) router.replace(LOGIN_URL); return Promise.reject(error); } diff --git a/frontend/src/stores/modules/user.ts b/frontend/src/stores/modules/user.ts index d52fc5a..e44c8f1 100644 --- a/frontend/src/stores/modules/user.ts +++ b/frontend/src/stores/modules/user.ts @@ -9,6 +9,7 @@ export const useUserStore = defineStore({ accessToken: "", refreshToken: "", isRefreshToken:false, + exp: Number(0), userInfo: {id:"", name: "admin" }, }), getters: {}, @@ -26,6 +27,9 @@ export const useUserStore = defineStore({ // Set setUserInfo setUserInfo(userInfo: UserState["userInfo"]) { this.userInfo = userInfo; + }, + setExp(exp: number) { + this.exp = exp; } }, persist: piniaPersistConfig(USER_STORE_KEY), diff --git a/frontend/src/views/login/components/LoginForm.vue b/frontend/src/views/login/components/LoginForm.vue index 7a7a35b..2c3618d 100644 --- a/frontend/src/views/login/components/LoginForm.vue +++ b/frontend/src/views/login/components/LoginForm.vue @@ -80,7 +80,6 @@ const tabsStore = useTabsStore() const keepAliveStore = useKeepAliveStore() const dictStore = useDictStore() -const isAutoLogin = ref(false) let publicKey: any = null; @@ -105,31 +104,23 @@ const login = (formEl: FormInstance | undefined) => { if (!valid) return loading.value = true try { - if (!isAutoLogin.value) { - let {data: publicKeyBase64}: { data: string } = await getPublicKey(loginForm.username, loginForm.checked) - //将base64格式的公钥转换为Forge可以使用的格式 - const publicKeyDer = forge.util.decode64(publicKeyBase64); - publicKey = forge.pki.publicKeyFromPem(forge.pki.publicKeyToPem(forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyDer)))); - } + let {data: publicKeyBase64}: { data: string } = await getPublicKey(loginForm.username) + //将base64格式的公钥转换为Forge可以使用的格式 + const publicKeyDer = forge.util.decode64(publicKeyBase64); + publicKey = forge.pki.publicKeyFromPem(forge.pki.publicKeyToPem(forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyDer)))); // 1.执行登录接口 const {data} = await loginApi({ username: forge.util.encode64(loginForm.username), - password: isAutoLogin.value ? loginForm.password : encryptPassword(loginForm.password), - checked: loginForm.checked + password: encryptPassword(loginForm.password), }) - if (loginForm.checked) { - localStorage.setItem("loginInfo", JSON.stringify({ - username: forge.util.encode64(loginForm.username), - password: isAutoLogin.value ? loginForm.password : encryptPassword(loginForm.password), - exp: Date.now() + 1000 * 60 * 60 * 24 * 30 - })) - } else { - localStorage.removeItem("loginInfo") - } userStore.setAccessToken(data.accessToken) userStore.setRefreshToken(data.refreshToken) userStore.setUserInfo(data.userInfo) + if(loginForm.checked){ + // userStore.setExp(Date.now() + 1000 * 60 * 60 * 24 * 30) + userStore.setExp(Date.now() + 1000 * 10) + } const response = await getDictList() const dictData = response.data as unknown as Dict[] await dictStore.initDictData(dictData) @@ -179,20 +170,6 @@ const encryptPassword = (password: string) => { return forge.util.encode64(encrypted); } -onBeforeMount(async () => { - let loginInfoJSON = localStorage.getItem("loginInfo") - if (loginInfoJSON) { - const loginInfo = JSON.parse(loginInfoJSON) - if (loginInfo.exp < Date.now()) { - localStorage.removeItem("loginInfo") - } else { - isAutoLogin.value = true - loginForm.username = forge.util.decode64(loginInfo.username) - loginForm.password = loginInfo.password - loginForm.checked = true - } - } -})