feat(server): 添加认证授权和日志记录功能
- 实现了 JWT 认证中间件,支持 token 验证和白名单路由 - 添加了登录接口,支持用户登录和 token 生成 - 集成了 log4js 日志系统,支持 mysql 和 koa 日志分类 - 配置了环境变量支持,添加了 SECRET_KEY 配置 - 重构了 MySQL 连接池配置,添加了查询日志记录 - 集成了 koa 路由和认证中间件,实现接口访问控制
This commit is contained in:
@@ -0,0 +1 @@
|
||||
SECRET_KEY=y7Y17cMV8fTzLTp
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import "./mysql/index.js"
|
||||
import "./koa/index.js"
|
||||
import "./log4js.js"
|
||||
|
||||
26
module/server/koa/auth.js
Normal file
26
module/server/koa/auth.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import * as log4js from "../log4js.js";
|
||||
|
||||
const whiteList = [
|
||||
'/',
|
||||
'/api/login',
|
||||
]
|
||||
|
||||
async function auth(ctx, next) {
|
||||
try {
|
||||
log4js.koa.debug("接口请求:", ctx.path)
|
||||
if (whiteList.includes(ctx.path)) {
|
||||
await next();
|
||||
return; // 终止后续验证逻辑
|
||||
}
|
||||
const token = ctx.request.headers.authorization?.split(' ')[1];
|
||||
if (!token) throw new Error('无token');
|
||||
ctx.user = jwt.verify(token, process.env.SECRET_KEY);
|
||||
await next();
|
||||
} catch (err) {
|
||||
ctx.status = 401;
|
||||
ctx.body = {msg: 'token无效或过期', code: 401};
|
||||
}
|
||||
}
|
||||
|
||||
export default auth;
|
||||
@@ -2,28 +2,30 @@ import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import config from "../config/index.js"
|
||||
import koaStatic from 'koa-static';
|
||||
import registry from "./registry.js";
|
||||
import * as log4js from "../log4js.js";
|
||||
import auth from "./auth.js";
|
||||
|
||||
const app = new Koa();
|
||||
const router = new Router();
|
||||
|
||||
|
||||
// 简单的路由示例
|
||||
router.get('/', (ctx) => {
|
||||
ctx.body = {message: 'Hello from Koa server!'};
|
||||
});
|
||||
|
||||
router.get('/api/test', (ctx) => {
|
||||
ctx.body = {message: 'This is a test API endpoint'};
|
||||
});
|
||||
|
||||
router.get('/api/config', (ctx) => {
|
||||
ctx.body = {data: config}
|
||||
})
|
||||
app.use(auth)
|
||||
app.use(router.routes());
|
||||
app.use(registry)
|
||||
app.use(router.allowedMethods());
|
||||
app.use(koaStatic('/www'))
|
||||
|
||||
const PORT = process.env.PORT || 3001;
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Koa server is running on port ${PORT}`);
|
||||
log4js.koa.info(`Koa server is running on port ${PORT}`);
|
||||
});
|
||||
|
||||
24
module/server/koa/login.js
Normal file
24
module/server/koa/login.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import Router from 'koa-router';
|
||||
import mysql from "../mysql/index.js";
|
||||
import jwt from "jsonwebtoken";
|
||||
import * as log4js from "../log4js.js";
|
||||
|
||||
const router = new Router()
|
||||
|
||||
router.post("/api/login", async (ctx) => {
|
||||
const {username, password} = ctx.request.body
|
||||
if (['admin'].includes(username)) return ctx.body = {code: 1, message: "该账户不对外开放"}
|
||||
const [rows] = await mysql.query("SELECT * FROM mir_web.player WHERE username = ? AND password = ?", [username, password])
|
||||
if (rows?.length == 1) {
|
||||
const token = jwt.sign(rows[0], process.env.SECRET_KEY, {expiresIn: '24h'});
|
||||
return ctx.body = {code: 0, message: "登录成功", token}
|
||||
}
|
||||
log4js.koa.error("用户登录失败", username)
|
||||
return ctx.body = {code: 1, message: "用户名或密码错误"}
|
||||
})
|
||||
|
||||
router.post("/api/enter_game", async (ctx) => {
|
||||
|
||||
const {srvId, account} = ctx.request.body
|
||||
})
|
||||
export default router.routes()
|
||||
5
module/server/koa/registry.js
Normal file
5
module/server/koa/registry.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import Router from 'koa-router';
|
||||
const router = new Router()
|
||||
|
||||
|
||||
export default router.routes()
|
||||
15
module/server/log4js.js
Normal file
15
module/server/log4js.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import log4js from "log4js";
|
||||
|
||||
export const configure = {
|
||||
appenders: {
|
||||
console: {type: "console"},
|
||||
},
|
||||
categories: {
|
||||
default: {appenders: ["console"], level: "ALL"},
|
||||
},
|
||||
}
|
||||
log4js.configure(configure)
|
||||
export const manager = log4js
|
||||
export const mysql = log4js.getLogger("mysql")
|
||||
export const koa = log4js.getLogger("koa")
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import mysql from "mysql2";
|
||||
import config from "../config/index.js";
|
||||
import * as log4js from "../log4js.js";
|
||||
|
||||
const pool = mysql.createPool({
|
||||
...config.mysql,
|
||||
host: config.mysql.host,
|
||||
port: config.mysql.port,
|
||||
user: config.mysql.user,
|
||||
password: config.mysql.password,
|
||||
connectionLimit: 10,
|
||||
queryFormat: function (sql, values) {
|
||||
const opts = { sql, values }
|
||||
this._resolveNamedPlaceholders(opts)
|
||||
return mysql2.format(
|
||||
log4js.mysql.debug(opts.sql, opts.values)
|
||||
return mysql.format(
|
||||
opts.sql,
|
||||
opts.values,
|
||||
this.config.stringifyObjects,
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
"main": "koa/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "nodemon index.js"
|
||||
"start": "node --env-file=.env index.js",
|
||||
"dev": "nodemon --exec \"node --env-file=.env\" index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"koa": "^2.15.0",
|
||||
"koa-router": "^12.0.0",
|
||||
"koa-static": "^5.0.0",
|
||||
"log4js": "^6.9.1",
|
||||
"mysql2": "^3.16.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user