项目初始化

This commit is contained in:
Stev_Wang
2026-01-04 17:19:04 +08:00
commit 93aae460af
41 changed files with 6922 additions and 0 deletions

View File

@@ -0,0 +1,176 @@
// 导入Express的Request和Response类型
import { Request, Response } from 'express';
// 导入bcrypt用于密码加密和验证
import bcrypt from 'bcrypt';
// 导入jsonwebtoken用于生成和验证JWT令牌
import jwt from 'jsonwebtoken';
// 导入数据源配置
import { AppDataSource } from '../config/database';
// 导入管理员用户模型
import { AdminUser } from '../models/AdminUser';
/**
* 管理员认证控制器
* 处理管理员登录、登出和获取当前用户信息等认证相关操作
*/
export class AdminAuthController {
/**
* 管理员登录
* 验证用户名和密码生成JWT令牌并设置到cookie中
* @param req - Express请求对象包含用户名和密码
* @param res - Express响应对象
*/
async login(req: Request, res: Response) {
try {
// 从请求体中获取用户名和密码
const { username, password } = req.body;
// 验证用户名和密码是否为空
if (!username || !password) {
return res.status(400).json({
success: false,
message: '用户名和密码不能为空'
});
}
// 获取管理员用户仓库
const adminUserRepository = AppDataSource.getRepository(AdminUser);
// 根据用户名查找管理员用户
const adminUser = await adminUserRepository.findOne({
where: { username }
});
// 用户不存在
if (!adminUser) {
return res.status(401).json({
success: false,
message: '用户名或密码错误'
});
}
// 验证密码是否正确
const isPasswordValid = await bcrypt.compare(password, adminUser.passwordHash);
// 密码错误
if (!isPasswordValid) {
return res.status(401).json({
success: false,
message: '用户名或密码错误'
});
}
// 检查账号状态是否被禁用
if (adminUser.status !== 1) {
return res.status(403).json({
success: false,
message: '账号已被禁用'
});
}
// 生成JWT令牌包含用户ID、用户名和角色ID
const token = jwt.sign(
{
id: adminUser.id,
username: adminUser.username,
roleId: adminUser.roleId
},
process.env.JWT_SECRET || 'your-secret-key',
{ expiresIn: '2h' }
);
// 将令牌设置到cookie中配置安全选项
res.cookie('admin_token', token, {
httpOnly: true, // 仅HTTP访问防止XSS攻击
secure: process.env.NODE_ENV === 'production', // 生产环境仅HTTPS
sameSite: 'strict', // 防止CSRF攻击
maxAge: 2 * 60 * 60 * 1000 // 2小时过期
});
// 返回登录成功响应
return res.json({
success: true,
message: '登录成功',
data: {
token,
user: {
id: adminUser.id,
username: adminUser.username,
realName: adminUser.realName,
roleId: adminUser.roleId
}
}
});
} catch (error) {
console.error('管理员登录失败:', error);
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
/**
* 管理员登出
* 清除cookie中的令牌
* @param req - Express请求对象
* @param res - Express响应对象
*/
async logout(req: Request, res: Response) {
try {
// 清除cookie中的令牌
res.clearCookie('admin_token');
return res.json({
success: true,
message: '退出登录成功'
});
} catch (error) {
console.error('管理员退出登录失败:', error);
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
/**
* 获取当前登录用户信息
* 根据请求中的管理员ID查询并返回用户信息
* @param req - Express请求对象包含已认证的管理员信息
* @param res - Express响应对象
*/
async getCurrentUser(req: any, res: Response) {
try {
// 获取管理员用户仓库
const adminUserRepository = AppDataSource.getRepository(AdminUser);
// 根据请求中的管理员ID查询用户信息
const adminUser = await adminUserRepository.findOne({
where: { id: req.admin.id }
});
// 用户不存在
if (!adminUser) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
// 返回用户信息
return res.json({
success: true,
data: {
id: adminUser.id,
username: adminUser.username,
realName: adminUser.realName,
roleId: adminUser.roleId
}
});
} catch (error) {
console.error('获取用户信息失败:', error);
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
}

View File

@@ -0,0 +1,142 @@
import { Request, Response } from 'express';
import axios from 'axios';
export class PlayerAuthController {
private readonly gameServerUrl: string;
constructor() {
this.gameServerUrl = process.env.GAME_SERVER_PROXY_URL || 'http://127.0.0.1:8080/tool/http';
}
async login(req: Request, res: Response) {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({
success: false,
message: '用户名和密码不能为空'
});
}
const response = await axios.post(
`${this.gameServerUrl}?code=auth/login`,
{
username,
password
},
{
proxy: false
}
);
if (response.data.success && response.data.code === 200) {
return res.json({
success: true,
message: '登录成功',
data: response.data.data
});
} else {
return res.status(401).json({
success: false,
message: response.data.message || '登录失败'
});
}
} catch (error: any) {
console.error('玩家登录失败:', error);
if (error.response) {
return res.status(error.response.status || 500).json({
success: false,
message: error.response.data?.message || '登录失败'
});
}
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
async logout(req: any, res: Response) {
try {
const token = req.headers?.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
message: '未授权'
});
}
await axios.post(
`${this.gameServerUrl}?code=auth/out_login`,
{},
{
headers: {
Authorization: token
},
proxy: false
}
);
return res.json({
success: true,
message: '退出登录成功'
});
} catch (error: any) {
console.error('玩家退出登录失败:', error);
return res.status(500).json({
success: false,
message: '退出登录失败'
});
}
}
async getAccountInfo(req: any, res: Response) {
try {
const token = req.headers?.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
message: '未授权'
});
}
const response = await axios.post(
`${this.gameServerUrl}?code=account/get_account`,
{},
{
headers: {
Authorization: token
},
proxy: false
}
);
if (response.data.success && response.data.code === 200) {
return res.json({
success: true,
data: response.data.data
});
} else {
return res.status(401).json({
success: false,
message: response.data.message || '获取账号信息失败'
});
}
} catch (error: any) {
console.error('获取账号信息失败:', error);
if (error.response) {
return res.status(error.response.status || 500).json({
success: false,
message: error.response.data?.message || '获取账号信息失败'
});
}
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
}