feat(server): 添加认证授权和日志记录功能

- 实现了 JWT 认证中间件,支持 token 验证和白名单路由
- 添加了登录接口,支持用户登录和 token 生成
- 集成了 log4js 日志系统,支持 mysql 和 koa 日志分类
- 配置了环境变量支持,添加了 SECRET_KEY 配置
- 重构了 MySQL 连接池配置,添加了查询日志记录
- 集成了 koa 路由和认证中间件,实现接口访问控制
This commit is contained in:
2025-12-24 23:48:14 +08:00
parent 18600b3015
commit 293fbd8bc8
9 changed files with 91 additions and 9 deletions

26
module/server/koa/auth.js Normal file
View 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;

View File

@@ -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}`);
});

View 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()

View File

@@ -0,0 +1,5 @@
import Router from 'koa-router';
const router = new Router()
export default router.routes()