using Asp.Versioning; using MAX.Framework.Dtos; using MAX.Framework.Security; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; using Store.Users.Contracts; namespace Store.Api.Controllers { [ApiController] [ApiVersion("1.0")] [Route("/v{version:apiVersion}/[controller]/[action]")] public class AuthController : ControllerBase { private readonly IUserAuthenticationService _users; private readonly ITokenService _tokenService; private readonly ICurrentUser _currentUser; private readonly IOnlineUserStore _onlineUserStore; private readonly ILogger _logger; public AuthController(ITokenService tokenService, ICurrentUser currentUser, IOnlineUserStore onlineUserStore, ILogger logger, IUserAuthenticationService users) { _users = users; _tokenService = tokenService; _currentUser = currentUser; _onlineUserStore = onlineUserStore; _logger = logger; } /// /// 登录:校验用户名/密码,签发数据库 Token(同账号支持多个独立会话) /// [HttpPost] [EndpointSummary("用户登录")] [AllowAnonymous] public async Task Login([FromBody] LoginRequest request) { _logger.LogInformation("login"); if (request is null || string.IsNullOrWhiteSpace(request.UserName) || string.IsNullOrWhiteSpace(request.Password)) { return ApiResult.Fail("用户名或密码不能为空", 400); } // 认证通过后才签发令牌,权限信息以用户模块中的数据库记录为准。 var user = await _users.Authenticate(request.UserName, request.Password, HttpContext.RequestAborted); if (user is null) return ApiResult.Fail("用户名或密码错误", 401); var claims = new List { new(JwtClaimTypes.UserName, user.UserName), }; if (request.DeviceId?.Length > 100 || request.DeviceName?.Length > 100) return ApiResult.Fail("设备信息最多 100 字符", 400); TokenResult token = _tokenService.CreateToken(claims, HttpContext.Connection.RemoteIpAddress?.ToString(), request.DeviceId, request.DeviceName); return ApiResult.Ok(token); } /// /// 退出登录:撤销当前客户端的服务端登录会话,令牌立即失效 /// [HttpPost] [EndpointSummary("退出登录")] [Authorize] public ApiResult Logout() { if (_currentUser.UserName is string username && _currentUser.GetClaimValue(JwtClaimTypes.Jti) is string jti) { _onlineUserStore.SignOutSession(username, jti); } return ApiResult.Ok(null); } /// /// 获取当前登录用户信息(需携带 Bearer Token) /// [HttpGet] [EndpointSummary("获取当前登录用户信息")] [Authorize] public ApiResult Me() { return ApiResult.Ok(new { UserName = _currentUser.UserName, NickName = _currentUser.NickName, }); } /// /// 在线人员列表(需携带 Bearer Token) /// [HttpGet] [EndpointSummary("获取在线人员列表")] [Authorize] public ApiResult OnlineUsers() { IReadOnlyList users = _onlineUserStore.GetOnlineUsers(); return ApiResult.Ok(new { Count = users.Count, Users = users, }); } } public class LoginRequest { public string UserName { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; public string? DeviceId { get; set; } public string? DeviceName { get; set; } } }