From ba43ad2bbce76f066ba07ebcf7839f4ed1168541 Mon Sep 17 00:00:00 2001 From: Miao_Spring <539943419@qq.com> Date: Tue, 2 Jul 2024 20:13:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0token=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 125 ++++++++++++++++++++++----------------------- src/App.vue | 91 +++++++++++++++++++++++---------- src/pinia/store.js | 9 +++- 3 files changed, 132 insertions(+), 93 deletions(-) diff --git a/server.js b/server.js index fc962b1..f30c9bd 100644 --- a/server.js +++ b/server.js @@ -11,7 +11,7 @@ import http from "http"; import { v4 as uuid4 } from "uuid"; import jwt from "jsonwebtoken"; import sha256 from "crypto-js/sha256.js"; -import Config from './miaoShareConfig.json' assert { type: 'json' }; +import Config from "./miaoShareConfig.json" assert { type: "json" }; import { verify } from "crypto"; // function loadJSON(path){ // return JSON.parse(fs.readFileSync(path).toString()); @@ -19,7 +19,7 @@ import { verify } from "crypto"; // const Config = loadJSON("./miaoShareConfig.json"); const HOST = "0.0.0.0"; -const PORT = Config.PORT +const PORT = Config.PORT; // const PORT = 17057; const fileDir = "./temp"; const dbPath = "./miaoShare.db"; @@ -66,7 +66,9 @@ const stmt_getFileSize = db.prepare(`SELECT fileSize FROM id2fileName WHERE id = const stmt_getFreeze = db.prepare(`SELECT freeze FROM id2fileName WHERE id = ?`); const stmt_getDownloadCredit = db.prepare(`SELECT downloadCredit FROM id2fileName WHERE id = ?`); const stmt_getFreezenIDs = db.prepare(`SELECT id,fileSize,sender_id FROM id2fileName WHERE freeze = 1`); -const stmt_insertId2FileName = db.prepare(`INSERT INTO id2fileName (id, fileName, timestamp, freeze, downloadCredit, fileSize, sender_id) VALUES (?, ?, ?, ?, ?, ?, ?)`); +const stmt_insertId2FileName = db.prepare( + `INSERT INTO id2fileName (id, fileName, timestamp, freeze, downloadCredit, fileSize, sender_id) VALUES (?, ?, ?, ?, ?, ?, ?)` +); const stmt_deleteExpireData = db.prepare(`DELETE FROM id2fileName WHERE freeze=1`); const stmt_freezeExpireData = db.prepare(`UPDATE id2fileName SET freeze=1 WHERE timestamp < ? OR downloadCredit < 1`); const stmt_updateDownloadCredit = db.prepare(`UPDATE id2fileName SET downloadCredit=downloadCredit-1 WHERE id = ?`); @@ -92,22 +94,22 @@ const db_getFileName = id => { // return null; // } // }; -const db_getFileInfo = (function(){ - const infoCache = {} - return function(id){ - if(infoCache[id]){ - return infoCache[id] +const db_getFileInfo = (function () { + const infoCache = {}; + return function (id) { + if (infoCache[id]) { + return infoCache[id]; } try { if (stmt_getFreeze.get(id)["freeze"] == 1) return null; const info = stmt_getFileInfo.get(id); - infoCache[id]=info + infoCache[id] = info; return info; } catch (e) { return null; } - } -})() + }; +})(); // 检查是否可下载 const db_downloadable = id => { try { @@ -139,13 +141,13 @@ const db_getUserUploadFilesSizeCount = id => { return stmt_getUserUploadFilesSizeCount.get(id)["uploadFilesSizeCount"]; }; -function db_updateUserUploadFilesSizeCount(id,size){ - return stmt_updateUserUploadFilesSizeCount.run(size,id) +function db_updateUserUploadFilesSizeCount(id, size) { + return stmt_updateUserUploadFilesSizeCount.run(size, id); } // 减 -function db_updateUserUploadFilesSizeCount_d(id,size){ - return stmt_updateUserUploadFilesSizeCount_d.run(size,id) +function db_updateUserUploadFilesSizeCount_d(id, size) { + return stmt_updateUserUploadFilesSizeCount_d.run(size, id); } // 更新存储的文件,删除已经被冻结的文件以及相关记录,然后冻结过期文件 @@ -155,9 +157,9 @@ const updateDBAndFiles = () => { stmt_deleteExpireData.run(); for (let row of rows) { let fileName = row["id"]; - let sid = row['sender_id'] - let fsize = row['fileSize'] - db_updateUserUploadFilesSizeCount_d(sid,fsize) + let sid = row["sender_id"]; + let fsize = row["fileSize"]; + db_updateUserUploadFilesSizeCount_d(sid, fsize); let path = fileDir + "/" + fileName; try { fs.unlink(path, e => { @@ -220,7 +222,7 @@ function uploadFile(req, res, fileName, downloadCredit, fileSize) { let id = generateId(); const fileStream = fs.createWriteStream(fileDir + "/" + id); db_insert(id, fileName, downloadCredit, fileSize, req.sender_id); - db_updateUserUploadFilesSizeCount(req.sender_id,fileSize) + db_updateUserUploadFilesSizeCount(req.sender_id, fileSize); // tempMap[id] = fileName; // console.log(tempMap); req.pipe(fileStream); @@ -289,41 +291,41 @@ function getFileInfo(req, res, fileId) { } } -const getUserGroup = (function(){ - const cache = {} - return function(userId){ - if(!cache[userId]){ - cache[userId]= stmt_getUserGroup.get(userId)['user_group'] +const getUserGroup = (function () { + const cache = {}; + return function (userId) { + if (!cache[userId]) { + cache[userId] = stmt_getUserGroup.get(userId)["user_group"]; } - return cache[userId] - } -})() + return cache[userId]; + }; +})(); // 验证token const verifyToken = (req, res, next) => { try { const token = req.headers.authorization.split(" ")[1]; // 从Authorization头中提取JWT - console.log(req.headers.authorization,token) + console.log(req.headers.authorization, token); let verifyData = jwt.verify(token, JWT_SK); if (verifyData.exp > parseInt(Date.now())) { throw "token has expired"; } - req.sender_id = verifyData.id + req.sender_id = verifyData.id; next(); } catch (err) { - console.log(err) + console.log(err); return res.status(401).json({ message: "Invalid token", err }); } }; app.use(express.static(PATH)); -app.post("/user/login", express.json(),function (req, res) { +app.post("/user/login", express.json(), function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "*"); res.header("Access-Control-Allow-Methods", "POST"); // console.log(req.body) let { id, pwd } = req.body; - console.log(req.body) + console.log(req.body); let pwdH = sha256(id + pwd).toString(); let userGroup = db_getPermissionGroup(id, pwdH); if (userGroup !== null) { @@ -336,33 +338,27 @@ app.post("/user/login", express.json(),function (req, res) { // console.log(req) }); - -app.post("/user/refrashToken", express.json(),function (req, res) { +app.post("/user/refrashToken", express.json(), function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "*"); res.header("Access-Control-Allow-Methods", "POST"); // console.log(req.body) - let { token } = req.body; - console.log(req.body) - - let verifyData = jwt.verify(token, JWT_SK); - if (verifyData.exp > parseInt(Date.now())) { - return res.status(401).json({ message: "Invalid token" }); + try { + const token = req.headers.authorization.split(" ")[1]; // 从Authorization头中提取JWT + // const token = req.body.token + console.log(token) + let verifyData = jwt.verify(token, JWT_SK); + if (verifyData.exp > parseInt(Date.now())) { + return res.status(401).json({ status: "Error", message: "Invalid token" }); + } + let id = verifyData.id; + let pwd = verifyData.pwd; + let new_token = jwt.sign({ id, pwd }, JWT_SK, { expiresIn: `${Config.tokenExpiresIn}h` }); + console.log({ token, new_token }); + res.end(JSON.stringify({ status: "Success", new_token })); + } catch (e) { + return res.status(401).json({ status: "Error", message: "Invalid token" }); } - let id = verifyData.id - let pwd = verifyData.pwd - let new_token = jwt.sign({ id, pwd }, JWT_SK, { expiresIn: `${Config.tokenExpiresIn}h` }); - res.end(JSON.stringify({ status: "Success", token })); - // let pwdH = sha256(id + pwd).toString(); - // let userGroup = db_getPermissionGroup(id, pwdH); - // if (userGroup !== null) { - // res.writeHead(200); - // let token = jwt.sign({ id, pwd }, JWT_SK, { expiresIn: `${Config.tokenExpiresIn}h` }); - // res.end(JSON.stringify({ status: "Success", userGroup, token })); - // } else { - // res.end(JSON.stringify({ status: "Error" })); - // } - // console.log(req) }); // app.all() app.post("/file/upload", verifyToken, function (req, res) { @@ -377,7 +373,10 @@ app.post("/file/upload", verifyToken, function (req, res) { if (!fileName) { res.statusCode = 500; res.end("FileName Not Found"); - } else if (fileSize > uploadMaxSize || db_getUserUploadFilesSizeCount(req.sender_id) + fileSize > Config.userGroupSetting[getUserGroup(req.sender_id)].cloudCapacity) { + } else if ( + fileSize > uploadMaxSize || + db_getUserUploadFilesSizeCount(req.sender_id) + fileSize > Config.userGroupSetting[getUserGroup(req.sender_id)].cloudCapacity + ) { res.statusCode = 500; res.end("Maximum size limit exceeded"); } else { @@ -481,11 +480,11 @@ function createGroupTableDB(gID, verify) { } // 插入信息 -function insertMessageByGID(gID, msg,type1, from, timestamp) { +function insertMessageByGID(gID, msg, type1, from, timestamp) { if (!generateStmt_insertMessage_map[gID]) { generateStmt_insertMessage_map[gID] = db.prepare(`INSERT INTO ${gID} (message,type,type1,sender, timestamp) VALUES (?, ?, ?, ?, ?)`); } - generateStmt_insertMessage_map[gID].run(msg, "gMsg",type1, from, timestamp); + generateStmt_insertMessage_map[gID].run(msg, "gMsg", type1, from, timestamp); } function updateActiveTimestamp(gID) { @@ -519,14 +518,14 @@ function getHistory(gID) { return groupsMap[gID].msgHistory; } -function broadcastMsg(gID, msg,type1, from) { +function broadcastMsg(gID, msg, type1, from) { const timestamp = parseInt(Date.now()); initMsgHistory(gID); updateActiveTimestamp(gID); - insertMessageByGID(gID, msg,type1, from, timestamp); + insertMessageByGID(gID, msg, type1, from, timestamp); - let bmsg = JSON.stringify({ type: `gMsg`,type1, gID, msg, from, timestamp }); - groupsMap[gID].msgHistory.push({ type: `gMsg`,type1, msg, from, timestamp }); + let bmsg = JSON.stringify({ type: `gMsg`, type1, gID, msg, from, timestamp }); + groupsMap[gID].msgHistory.push({ type: `gMsg`, type1, msg, from, timestamp }); for (let socket of groupsMap[gID].member) { socket.send(bmsg); } @@ -540,7 +539,7 @@ function initMsgHistory(gID) { .prepare(`SELECT message,type,type1,sender,timestamp FROM ${gID}`) .all() .map(v => { - return { type: v.type,type1:v.type1, msg: v.message, from: v.sender, timestamp: v.timestamp }; + return { type: v.type, type1: v.type1, msg: v.message, from: v.sender, timestamp: v.timestamp }; }); // console.log(msgHistory) groupsMap[gID] = { verify, member: [], msgHistory }; @@ -586,7 +585,7 @@ wss.on("connection", socket => { } } else if (type === "message") { let gID = msg.gID; - broadcastMsg(gID, msg.msg,msg.type1, uuid); + broadcastMsg(gID, msg.msg, msg.type1, uuid); } else if (type === "heartbeat") { socket.send(JSON.stringify({ type: "sMsg", type1: "heartbeat" })); } else if (type === "uuid") { diff --git a/src/App.vue b/src/App.vue index 57be884..64a5039 100644 --- a/src/App.vue +++ b/src/App.vue @@ -6,8 +6,8 @@ import chat from "./views/chat.vue"; import login from "./views/login.vue"; import account from "./views/accountInfo.vue"; import getQueryString from '@/func/getQuery' -import { NNotificationProvider, NMessageProvider, NCard, NMenu, NIcon,NModalProvider } from 'naive-ui' -import { ref, watch, h ,shallowRef, onMounted, computed} from "vue"; +import { NNotificationProvider, NMessageProvider, NCard, NMenu, NIcon, NModalProvider } from 'naive-ui' +import { ref, watch, h, shallowRef, onMounted, computed } from "vue"; // import { useRoute } from "vue-router"; import { CloudUploadOutline as uploadIcon, @@ -16,18 +16,25 @@ import { ChatbubblesOutline as chatIcon, SettingsOutline as settingIcon, FootstepsOutline as AccountIcon - + } from '@vicons/ionicons5' import { useSettingStore } from "@/pinia/store"; +import config from "../miaoShareConfig.json" // console.log(process.env.NODE_ENV) const settingData = useSettingStore(); +const serverPort = settingData.serverPort; +const baseUrl = + location.protocol + "//" + location.hostname + ":" + serverPort + "/"; +const tokenExpiresIn = config.tokenExpiresIn + + const activePage = ref('upload') const isComponent = shallowRef(upload) watch(activePage, () => { - isComponent.value={upload,download,setting,chat,login,account}[activePage.value] + isComponent.value = { upload, download, setting, chat, login, account }[activePage.value] }) function renderIcon(icon) { return () => h(NIcon, null, { default: () => h(icon) }) @@ -38,7 +45,7 @@ const menuOptions = ref([ label: '上传', key: 'upload', icon: renderIcon(uploadIcon), - disabled:computed(()=>{ + disabled: computed(() => { // console.log(settingData) return settingData.token === null }) @@ -47,7 +54,7 @@ const menuOptions = ref([ label: '下载', key: 'download', icon: renderIcon(downloadIcon), - disabled:computed(()=>{ + disabled: computed(() => { return settingData.token === null }) }, @@ -55,7 +62,7 @@ const menuOptions = ref([ label: 'Chat', key: 'chat', icon: renderIcon(chatIcon), - disabled:computed(()=>{ + disabled: computed(() => { return settingData.token === null }) }, @@ -63,15 +70,15 @@ const menuOptions = ref([ label: '设置', key: 'setting', icon: renderIcon(settingIcon), - disabled:computed(()=>{ + disabled: computed(() => { return settingData.token === null }) }, { - label:'账户', - key:'account', + label: '账户', + key: 'account', icon: renderIcon(AccountIcon), - disabled:computed(()=>{ + disabled: computed(() => { return settingData.token === null }) } @@ -86,22 +93,48 @@ const menuOptions = ref([ // } -onMounted(()=>{ + + +onMounted(async () => { let aP = getQueryString('aP') // console.log(aP) - if(aP){ + if (aP) { activePage.value = aP } - if(settingData.token === null){ + if (settingData.getToken() === null) { aP = activePage.value activePage.value = 'login' // 登录后跳原来的activePage - const w = watch(()=>settingData.token,()=>{ + const w = watch(() => settingData.token, () => { activePage.value = aP w() }) - }else{ + } else { // 刷新token + (async function refreshToken() { + const old_token = settingData.getToken() + console.log(old_token) + const response = await fetch(`${baseUrl}user/refrashToken`, { + // credentials: 'include', + method: "POST", + headers: { + 'Authorization': `Bearer ${settingData.token}`, + "Content-Type": "application/json" + }, + // body: JSON.stringify({ + // token:settingData.token + // }) + }); + console.log(response) + let data = await response.json() + if (data.status === 'Error') { + console.log('falied') + } else { + // console.log(data) + localStorage.setItem('token', data.new_token) + localStorage.setItem('tokenExpiredTime', parseInt(Date.now()) + parseInt(tokenExpiresIn) * 3600000) + } + })() } }) @@ -111,16 +144,17 @@ onMounted(()=>{ - - + + -
- - - -
+
+ + + +
@@ -144,14 +178,15 @@ onMounted(()=>{ height: 90vh; } -#menu{ - width: 100%; +#menu { + width: 100%; height: auto; /* background-color: blue; */ padding-top: 5px; - border-bottom: 1px solid rgb(60, 60, 60, 0.1); + border-bottom: 1px solid rgb(60, 60, 60, 0.1); user-select: none } + @media screen and (max-width:768px) { #theCard { width: 100vw; diff --git a/src/pinia/store.js b/src/pinia/store.js index 6e652a5..9c4c15d 100644 --- a/src/pinia/store.js +++ b/src/pinia/store.js @@ -5,7 +5,7 @@ const userID = localStorage.getItem('userID'); const userGroup = localStorage.getItem('userGroup'); const tokenExpiresIn = config.tokenExpiresIn -if(!localStorage.getItem('tokenExpiredTime') || +if(localStorage.getItem('tokenExpiredTime') == null || parseInt(localStorage.getItem('tokenExpiredTime')) < parseInt(Date.now())){ localStorage.removeItem('token') } @@ -47,8 +47,10 @@ export const useSettingStore = defineStore("setting", { actions: { setJWT( token,keepTokenLocal ){ this.token = token - if(keepTokenLocal) + if(keepTokenLocal){ localStorage.setItem('token',token) + localStorage.setItem('tokenExpiredTime',parseInt(Date.now())+parseInt(tokenExpiresIn)*3600000) + } }, setUserID( id,keepTokenLocal ){ this.userID = id @@ -59,6 +61,9 @@ export const useSettingStore = defineStore("setting", { this.userGroup = g if(keepTokenLocal) localStorage.setItem('userGroup',g) + }, + getToken(){ + return localStorage.getItem('token') } // increment() { // this.count++;