From f7d28672b76b6a254b0f9cda5d003caf841d76e3 Mon Sep 17 00:00:00 2001 From: LingandRX Date: Mon, 30 Dec 2024 22:10:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(session):=20=E4=BD=BF=E7=94=A8=20Redis=20?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E4=BC=9A=E8=AF=9D=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Redis 配置和连接逻辑 - 更新 express-session 配置,使用 RedisStore 存储会话 - 修改 .env 和 .gitignore 文件,添加 Redis 相关配置 - 更新用户登录和会话管理相关代码 --- .env | 6 + .gitignore | 10 +- app.js | 25 +++- common/constant/httpStatus.js | 4 +- config/{message.js => messages.js} | 0 {db => config}/mongodbConfig.js | 0 controllers/userController.js | 2 +- package-lock.json | 230 +++++++++++++++++++++++++++-- package.json | 7 +- routes/index.js | 8 +- utils/loginUtil.js | 2 +- 11 files changed, 265 insertions(+), 29 deletions(-) create mode 100644 .env rename config/{message.js => messages.js} (100%) rename {db => config}/mongodbConfig.js (100%) diff --git a/.env b/.env new file mode 100644 index 0000000..3c81611 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +MONGO_ACCOUNT=mongo_yNWy6K +MONGO_PASSWORD=mongo_pPGmE3 +SESSION_SECRET=secret +REDIS_HOST=122.152.201.90 +REDIS_PORT=6379 +REDIS_PASSWORD=redis_spHFRW \ No newline at end of file diff --git a/.gitignore b/.gitignore index c6bba59..fbf319e 100644 --- a/.gitignore +++ b/.gitignore @@ -73,11 +73,11 @@ web_modules/ .yarn-integrity # dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local +# .env +# .env.development.local +# .env.test.local +# .env.production.local +# .env.local # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/app.js b/app.js index 9b487ae..8f3b625 100644 --- a/app.js +++ b/app.js @@ -4,20 +4,27 @@ const path = require('path') const logger = require('morgan') const cors = require('cors') const session = require('express-session') +const { RedisStore } = require('connect-redis') +const Redis = require('ioredis') const cookieParser = require('cookie-parser') const indexRouter = require('./routes/index') const userRouter = require('./routes/userRouter') const accountRouter = require('./routes/accountRouter') +require('dotenv').config() // mongodb数据库连接 -const { connectMongoDB } = require('./db/mongodbConfig') +const { connectMongoDB } = require('./config/mongodbConfig') const loginUtil = require('./utils/loginUtil') -const app = express() +// 初始化 Redis 客户端 +const redisClient = new Redis({ + host: process.env.REDIS_HOST, + port: process.env.REDIS_PORT || 6379, + password: process.env.REDIS_PASSWORD, + db: 0 +}) -// 导入env -require('dotenv').config() -const loginSecret = process.env.SESSION_SECRET +const app = express() app.use(logger('dev')) app.use(express.json()) @@ -27,12 +34,14 @@ app.use(cookieParser()) app.use( session({ name: 'identityKey', - secret: loginSecret, + store: new RedisStore({ client: redisClient }), // 正确的方式,不要使用 new RedisStore(),直接传递配置 + secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { secure: false, - maxAge: 1000 * 60 * 10 + httpOnly: true, + maxAge: 24 * 60 * 60 * 1000 } }) ) @@ -41,7 +50,7 @@ const corsOptions = { origin: 'http://localhost:5173', // 指定允许的源 credentials: true, // 允许发送凭据(如 cookies) optionsSuccessStatus: 200 // 一些旧的浏览器(IE11, various SmartTVs)需要这个 -}; +} app.use(cors(corsOptions)) diff --git a/common/constant/httpStatus.js b/common/constant/httpStatus.js index 3fdc6cf..bdad8fa 100644 --- a/common/constant/httpStatus.js +++ b/common/constant/httpStatus.js @@ -1,7 +1,7 @@ /** * HTTP 状态码常量 */ -export const HTTP_STATUS = { +const HTTP_STATUS = { // 信息响应 (100–199) /** @type {number} 继续 */ CONTINUE: 100, @@ -66,3 +66,5 @@ export const HTTP_STATUS = { /** @type {number} 网关超时 */ GATEWAY_TIMEOUT: 504 } + +module.exports = HTTP_STATUS diff --git a/config/message.js b/config/messages.js similarity index 100% rename from config/message.js rename to config/messages.js diff --git a/db/mongodbConfig.js b/config/mongodbConfig.js similarity index 100% rename from db/mongodbConfig.js rename to config/mongodbConfig.js diff --git a/controllers/userController.js b/controllers/userController.js index a03b92e..7ddb7bb 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -1,7 +1,7 @@ const { body, validationResult } = require('express-validator') const userService = require('../services/userService') const FetchResult = require('../common/web/fetchResult') -const messages = require('../config/message') +const messages = require('../config/messages') const { HTTP_STATUS } = require('../common/constant/httpStatus') exports.getAllUsers = async (res) => { diff --git a/package-lock.json b/package-lock.json index 0b4ca9a..1d97da0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,24 +9,33 @@ "version": "0.0.0", "dependencies": { "bcrypt": "^5.1.1", + "connect-redis": "^8.0.1", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", "dotenv": "^16.4.7", "express": "^4.19.2", "express-async-handler": "^1.2.0", - "express-session": "^1.18.0", + "express-session": "^1.18.1", "express-validator": "^7.2.0", "http-errors": "~1.6.3", + "ioredis": "^5.4.2", "jade": "^0.29.0", "mongoose": "^8.3.4", "morgan": "~1.9.1", - "nodemon": "^3.1.0" + "nodemon": "^3.1.0", + "redis": "^4.7.0" }, "devDependencies": { "prettier": "^3.4.2" } }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "license": "MIT" + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -118,6 +127,65 @@ "sparse-bitfield": "^3.0.3" } }, + "node_modules/@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/client": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@redis/client/-/client-1.6.0.tgz", + "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", + "license": "MIT", + "dependencies": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/json": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/@redis/json/-/json-1.0.7.tgz", + "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==", + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/search": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@redis/search/-/search-1.2.0.tgz", + "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==", + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/time-series": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@redis/time-series/-/time-series-1.1.0.tgz", + "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==", + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -422,6 +490,15 @@ "node": ">=10" } }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -443,6 +520,18 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/connect-redis": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/connect-redis/-/connect-redis-8.0.1.tgz", + "integrity": "sha512-7iOI214/r15ahvu0rqKCHhsgpMdOgyLwqlw/icSTnnAR75xFvMyfxAE+je4M87rZLjDlKzKcTc48XxQXYFsMgA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "express-session": ">=1" + } + }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -552,6 +641,15 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -709,11 +807,12 @@ "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "node_modules/express-session": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz", - "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==", + "version": "1.18.1", + "resolved": "https://registry.npmmirror.com/express-session/-/express-session-1.18.1.tgz", + "integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==", + "license": "MIT", "dependencies": { - "cookie": "0.6.0", + "cookie": "0.7.2", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", @@ -727,9 +826,10 @@ } }, "node_modules/express-session/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.2", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -958,6 +1058,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generic-pool": { + "version": "3.9.0", + "resolved": "https://registry.npmmirror.com/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -1153,6 +1262,53 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, + "node_modules/ioredis": { + "version": "5.4.2", + "resolved": "https://registry.npmmirror.com/ioredis/-/ioredis-5.4.2.tgz", + "integrity": "sha512-0SZXGNGZ+WzISQ67QDyZ2x0+wVxjjUndtD8oSeik/4ajifeiRufed8fCb8QW8VMyi4MXcS+UO1k/0NGhvq1PAg==", + "license": "MIT", + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ioredis/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/ioredis/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", @@ -1262,6 +1418,18 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT" + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz", @@ -1894,6 +2062,44 @@ "node": ">=8.10.0" } }, + "node_modules/redis": { + "version": "4.7.0", + "resolved": "https://registry.npmmirror.com/redis/-/redis-4.7.0.tgz", + "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", + "license": "MIT", + "workspaces": [ + "./packages/*" + ], + "dependencies": { + "@redis/bloom": "1.2.0", + "@redis/client": "1.6.0", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.7", + "@redis/search": "1.2.0", + "@redis/time-series": "1.1.0" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2129,6 +2335,12 @@ "optional": true, "peer": true }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT" + }, "node_modules/statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", diff --git a/package.json b/package.json index 6402910..82bd854 100644 --- a/package.json +++ b/package.json @@ -8,19 +8,22 @@ }, "dependencies": { "bcrypt": "^5.1.1", + "connect-redis": "^8.0.1", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", "dotenv": "^16.4.7", "express": "^4.19.2", "express-async-handler": "^1.2.0", - "express-session": "^1.18.0", + "express-session": "^1.18.1", "express-validator": "^7.2.0", "http-errors": "~1.6.3", + "ioredis": "^5.4.2", "jade": "^0.29.0", "mongoose": "^8.3.4", "morgan": "~1.9.1", - "nodemon": "^3.1.0" + "nodemon": "^3.1.0", + "redis": "^4.7.0" }, "devDependencies": { "prettier": "^3.4.2" diff --git a/routes/index.js b/routes/index.js index 14be9fc..b9bff97 100644 --- a/routes/index.js +++ b/routes/index.js @@ -2,9 +2,13 @@ var express = require('express') var router = express.Router() const userController = require('../controllers/userController') - router.get('/', function (req, res, next) { - // res.send('respond with a resource') + if (!req.session.views) { + req.session.views = 1 + } else { + req.session.views++ + } + res.send(`你访问了 ${req.session.views} 次`) }) router.post('/login', userController.login) diff --git a/utils/loginUtil.js b/utils/loginUtil.js index 5b7c95e..46a2d4e 100644 --- a/utils/loginUtil.js +++ b/utils/loginUtil.js @@ -1,4 +1,4 @@ -import FetchResult from '../common/web/fetchResult.js' +const FetchResult = require('../common/web/fetchResult.js') exports.authenticateSession = async (req, res, next) => { if (req.session.user) {