Files
MHXY_WEB_VUE/backend/src/controllers/adminAuthController.ts
2026-01-04 17:19:04 +08:00

177 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 导入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: '服务器内部错误'
});
}
}
}