v0.6测试
This commit is contained in:
@@ -15,6 +15,7 @@ from datetime import datetime
|
||||
from models.user import UserModel
|
||||
from models.student import StudentModel
|
||||
from models.admin_role import AdminRoleModel
|
||||
from services.log_service import LogService
|
||||
from utils.security import security
|
||||
from utils.jwt_handler import jwt_handler
|
||||
from utils.redis_client import RedisClient
|
||||
@@ -28,13 +29,14 @@ class AuthService:
|
||||
"""认证服务"""
|
||||
|
||||
@staticmethod
|
||||
async def login(username: str, password: str, ip: str) -> Dict[str, Any]:
|
||||
async def login(username: str, password: str, ip: str, user_agent: str = None) -> Dict[str, Any]:
|
||||
"""
|
||||
用户登录
|
||||
"""
|
||||
# 检查登录失败次数
|
||||
attempts = await RedisClient.get(f"login_attempts:{username}")
|
||||
if attempts and int(attempts) >= 5:
|
||||
await LogService.write_login_log(username, 0, ip, user_agent, "登录失败次数过多")
|
||||
return {"success": False, "message": "登录失败次数过多,请15分钟后重试"}
|
||||
|
||||
# 获取用户信息
|
||||
@@ -42,15 +44,18 @@ class AuthService:
|
||||
|
||||
if not user:
|
||||
await RedisClient.set_login_attempts(username)
|
||||
await LogService.write_login_log(username, 0, ip, user_agent, "用户名或密码错误")
|
||||
return {"success": False, "message": "用户名或密码错误"}
|
||||
|
||||
# 验证密码
|
||||
if not security.verify_password(password, user["password_hash"]):
|
||||
await RedisClient.set_login_attempts(username)
|
||||
await LogService.write_login_log(username, 0, ip, user_agent, "用户名或密码错误")
|
||||
return {"success": False, "message": "用户名或密码错误"}
|
||||
|
||||
# 检查账号状态
|
||||
if user["status"] != 1:
|
||||
await LogService.write_login_log(username, 0, ip, user_agent, "账号已被禁用")
|
||||
return {"success": False, "message": "账号已被禁用"}
|
||||
|
||||
# 清除登录失败记录
|
||||
@@ -80,6 +85,8 @@ class AuthService:
|
||||
# 确定跳转路径
|
||||
redirect = AuthService._get_redirect_path(user["user_type"], role)
|
||||
|
||||
await LogService.write_login_log(username, 1, ip, user_agent)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"token": token,
|
||||
|
||||
57
backend/services/log_service.py
Normal file
57
backend/services/log_service.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# ===========================================
|
||||
# 班级操行分管理系统 - 后端服务
|
||||
#
|
||||
# 开发者: Canglan
|
||||
# 联系方式: admin@sea-studio.top
|
||||
# 版权归属: Sea Network Technology Studio
|
||||
# 许可证: MIT License
|
||||
#
|
||||
# 版权所有 © Sea Network Technology Studio
|
||||
# ===========================================
|
||||
|
||||
from models.log import LoginLogModel, OperationLogModel
|
||||
from middleware.permission import PermissionChecker
|
||||
from utils.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class LogService:
|
||||
"""日志服务"""
|
||||
|
||||
@staticmethod
|
||||
async def write_login_log(username: str, login_result: int, ip: str, user_agent: str = None, fail_reason: str = None):
|
||||
"""
|
||||
写入登录日志(异步,不阻塞主流程)
|
||||
"""
|
||||
try:
|
||||
await LoginLogModel.create(
|
||||
username=username,
|
||||
login_result=login_result,
|
||||
ip_address=ip,
|
||||
user_agent=user_agent,
|
||||
fail_reason=fail_reason
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"写入登录日志失败: {e}")
|
||||
|
||||
@staticmethod
|
||||
async def write_operation_log(operator_id: int, operator_name: str, operator_role: str,
|
||||
operation_type: str, target_type: str = None,
|
||||
target_id: int = None, details: str = None, ip: str = None):
|
||||
"""
|
||||
写入操作日志(异步,不阻塞主流程)
|
||||
"""
|
||||
try:
|
||||
await OperationLogModel.create(
|
||||
operator_id=operator_id,
|
||||
operator_name=operator_name,
|
||||
operator_role=operator_role,
|
||||
operation_type=operation_type,
|
||||
target_type=target_type,
|
||||
target_id=target_id,
|
||||
details=details,
|
||||
ip_address=ip
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"写入操作日志失败: {e}")
|
||||
Reference in New Issue
Block a user