diff --git a/Server/src/APIs/Console/GetLoginStatus.ts b/Server/src/APIs/Console/GetLoginStatus.ts new file mode 100644 index 0000000..1096e8b --- /dev/null +++ b/Server/src/APIs/Console/GetLoginStatus.ts @@ -0,0 +1,31 @@ +import { API, RequestData } from "../../Plugs/API/API"; +import ServerStdResponse from "../../ServerStdResponse"; +import MySQLConnection from '../../Plugs/MySQLConnection' +import Auth from "../../Plugs/Middleware/Auth"; +import jwt from "jsonwebtoken"; +import config from "../../config"; + +// 获取登录状态 +class GetLoginStatus extends API { + constructor() { + super('GET', '/console/loginStatus', Auth); + } + + public async onRequset(data: RequestData, res: any) { + const { uuid } = data._jwt; + const jwtPayload = { + uuid, + loginTime: Date.now() + } + + const token = jwt.sign(jwtPayload, config.jwt.secret, { expiresIn: config.jwt.expiresIn }); + return res.json({ + ...ServerStdResponse.OK, + data: { + token + } + }); + } +} + +export default GetLoginStatus; \ No newline at end of file diff --git a/Server/src/Server/Server.ts b/Server/src/Server/Server.ts index 305aaac..4ddb16c 100644 --- a/Server/src/Server/Server.ts +++ b/Server/src/Server/Server.ts @@ -25,6 +25,7 @@ import DelResource from '../APIs/Console/DelResource' import SaveBlog from '../APIs/Console/SaveBlog' import DelBlog from '../APIs/Console/DelBlog' import GetOSSToken from "../APIs/Console/GetOSSToken"; +import GetLoginStatus from "../APIs/Console/GetLoginStatus"; class Server { private logger = new Logger('Server'); @@ -56,6 +57,7 @@ class Server { this.apiLoader.add(SetBlogPasswd); this.apiLoader.add(DelBlog); this.apiLoader.add(GetOSSToken); + this.apiLoader.add(GetLoginStatus); this.apiLoader.start(config.apiPort); } diff --git a/tonecn/src/views/Console/Dashboard.vue b/tonecn/src/views/Console/Dashboard.vue index b3efd5a..56cf209 100644 --- a/tonecn/src/views/Console/Dashboard.vue +++ b/tonecn/src/views/Console/Dashboard.vue @@ -6,6 +6,7 @@ import Utils from '../../components/Console/Utils.vue' import FileOnline from '../../components/Console/FileOnline.vue' import { shallowRef, ref, onMounted, onUnmounted } from 'vue'; import { ElMessage, ElMessageBox } from 'element-plus'; +import { request } from '@/lib/request' const tabComponent = shallowRef(Resources); const menuCollapse = ref(false) const handleResize = () => { @@ -35,6 +36,29 @@ const logout = () => { onMounted(async () => { handleResize() window.addEventListener('resize', handleResize); + + const refreshToken = async () => { + // 判断jwt过期时间并定期刷新 + if (localStorage.getItem('jwtToken')) { + const binaryString = atob(localStorage.getItem('jwtToken')!.split('.')[1]); + const jwtPayload = JSON.parse(binaryString); + if ((jwtPayload.exp - Math.floor(Date.now() / 1000)) < 0) { + // token已过期 + localStorage.clear() + window.location.reload() + } + if ((jwtPayload.exp - Math.floor(Date.now() / 1000)) / (jwtPayload.exp - jwtPayload.iat) < 0.3) { + // 重新获取token + console.log("token有效期 ", (jwtPayload.exp - Math.floor(Date.now() / 1000)) / (jwtPayload.exp - jwtPayload.iat), "不足%30,正在重新获取Token") + let res: any = await request.get('/console/loginStatus'); + if (res.code == 0) { + localStorage.setItem('jwtToken', res.data.token) + } + } + } + } + setInterval(refreshToken, 1000 * 60 * 30);// 30 分钟判定一次token有效期 + refreshToken() }) onUnmounted(async () => { window.removeEventListener('resize', handleResize);