using Microsoft.AspNetCore.Mvc; using MediatR; using CellularManagement.Application.Features.Auth.Commands.AuthenticateUser; using CellularManagement.Application.Features.Auth.Commands.RegisterUser; using CellularManagement.Application.Features.Auth.Commands.RefreshToken; using CellularManagement.Application.Common; using Microsoft.Extensions.Logging; using CellularManagement.Domain.Services; using Microsoft.Extensions.Caching.Memory; using CellularManagement.Infrastructure.Configurations; using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Http; using CellularManagement.Presentation.Abstractions; using CellularManagement.Application.Features.Auth.Commands.Login; using Swashbuckle.AspNetCore.Filters; using CellularManagement.Domain.Common; namespace CellularManagement.Presentation.Controllers; /// /// 认证控制器 /// 提供用户认证相关的 API 接口,包括登录和注册功能 /// public class AuthController : ApiController { private readonly ILogger _logger; private readonly ICacheService _cache; private readonly AuthConfiguration _authConfig; /// /// 初始化认证控制器 /// /// MediatR 中介者,用于处理命令和查询 /// 日志记录器 /// 缓存服务 /// 认证配置 public AuthController( IMediator mediator, ILogger logger, ICacheService cache, IOptions authConfig) : base(mediator) { _logger = logger; _cache = cache; _authConfig = authConfig.Value; } /// /// 用户登录 /// /// /// 示例请求: /// /// POST /api/auth/login /// { /// "userNameOrEmail": "用户名或邮箱", /// "password": "密码" /// } /// /// /// 登录命令,包含用户名/邮箱和密码 /// /// 登录结果,包含: /// - 成功:返回用户信息和访问令牌 /// - 失败:返回错误信息 /// /// 登录成功,返回用户信息和令牌 /// 登录失败,返回错误信息 /// 登录尝试次数过多 [HttpPost()] [SwaggerRequestExample(typeof(LoginRequest), typeof(LoginRequestExample))] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status429TooManyRequests)] public async Task>> Login([FromBody] AuthenticateUserCommand command) { try { // 检查登录尝试次数 var cacheKey = string.Format(_authConfig.LoginAttemptsCacheKeyFormat, command.UserName); var attempts = _cache.Get(cacheKey); if (attempts >= _authConfig.MaxLoginAttempts) { _logger.LogWarning("用户 {UserName} 登录尝试次数过多", command.UserName); return StatusCode(StatusCodes.Status429TooManyRequests, OperationResult.CreateFailure("登录尝试次数过多,请稍后再试")); } // 执行登录 var result = await mediator.Send(command); if (!result.IsSuccess) { // 增加登录尝试次数 var options = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromMinutes(_authConfig.LoginAttemptsWindowMinutes)); _cache.Set(cacheKey, attempts + 1, options); _logger.LogWarning("用户 {UserName} 登录失败: {Error}", command.UserName, result.ErrorMessages?.FirstOrDefault()); } else { // 清除登录尝试次数 _cache.Remove(cacheKey); _logger.LogInformation("用户 {UserName} 登录成功", command.UserName); } _logger.LogWarning($"Bearer {result.Data.AccessToken}"); return Ok(result); } catch (Exception ex) { _logger.LogError(ex, "用户 {UserName} 登录时发生异常", command.UserName); return StatusCode(StatusCodes.Status500InternalServerError, OperationResult.CreateFailure("系统错误,请稍后重试")); } } /// /// 用户注册 /// /// /// 示例请求: /// /// POST /api/auth/register /// { /// "userName": "用户名", /// "email": "邮箱", /// "password": "密码", /// "confirmPassword": "确认密码", /// "phoneNumber": "手机号" /// } /// /// /// 注册命令,包含用户注册信息 /// /// 注册结果,包含: /// - 成功:返回用户ID /// - 失败:返回错误信息 /// /// 注册成功,返回用户ID /// 注册失败,返回错误信息 [HttpPost()] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] public async Task>> Register([FromBody] RegisterUserCommand command) { try { // 执行注册 var result = await mediator.Send(command); if (result.IsSuccess) { _logger.LogInformation("用户 {UserName} 注册成功", command.UserName); } else { _logger.LogWarning("用户 {UserName} 注册失败: {Error}", command.UserName, result.ErrorMessages?.FirstOrDefault()); } return Ok(result); } catch (Exception ex) { _logger.LogError(ex, "用户 {UserName} 注册时发生异常", command.UserName); return StatusCode(StatusCodes.Status500InternalServerError, OperationResult.CreateFailure("系统错误,请稍后重试")); } } /// /// 刷新令牌 /// /// /// 示例请求: /// /// POST /api/auth/refresh-token /// { /// "refreshToken": "刷新令牌" /// } /// /// /// 刷新令牌命令 /// /// 刷新结果,包含: /// - 成功:返回用户信息和新的访问令牌 /// - 失败:返回错误信息 /// /// 刷新成功,返回用户信息和新的令牌 /// 刷新失败,返回错误信息 [HttpPost()] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] public async Task>> RefreshToken([FromBody] RefreshTokenCommand command) { try { var result = await mediator.Send(command); if (result.IsSuccess) { _logger.LogInformation("令牌刷新成功"); } else { _logger.LogWarning("令牌刷新失败: {Error}", result.ErrorMessages?.FirstOrDefault()); } return Ok(result); } catch (Exception ex) { _logger.LogError(ex, "刷新令牌时发生异常"); return StatusCode(StatusCodes.Status500InternalServerError, OperationResult.CreateFailure("系统错误,请稍后重试")); } } }