using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Admin.Core.Common; using Admin.Core.Extensions; using Admin.Core.IService; using Admin.Core.IService.ISys; using Admin.Core.Model; using Admin.Core.Model.Sys; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using UAParser; namespace Admin.Core.Api { /// /// 登录管理 /// [Produces("application/json")] [Route("api/Login")] [Authorize(Permissions.Name)] public class LoginController : BaseApiUserController { readonly ISysMenuService _sysMenuService; readonly ISysPermissionService _sysPermissionService; readonly ISysLoginInfoService _sysLoginInfoService; readonly ICaptcha _captcha; readonly ISysConfigService _sysConfigService; readonly PermissionRequirement _requirement; /// /// 构造函数注入 /// /// /// /// /// /// /// /// public LoginController(ISysUserService sysUserService, ISysMenuService sysMenuService, ISysPermissionService sysPermissionService, ICaptcha captcha, PermissionRequirement requirement, ISysLoginInfoService sysLoginInfoService, ISysConfigService sysConfigService) : base(sysUserService) { _sysUserService = sysUserService; _sysMenuService = sysMenuService; _sysPermissionService = sysPermissionService; _sysLoginInfoService = sysLoginInfoService; _captcha = captcha; _sysConfigService = sysConfigService; _requirement = requirement; } /// /// 登录获取Token-JWT /// /// /// [HttpPost] [Route("Login")] [AllowAnonymous] public async Task> GetJwtToken([FromBody] LoginBody loginBody) { string jwtStr = string.Empty; if (!loginBody.IsNotEmptyOrNull() || string.IsNullOrEmpty(loginBody.LoginName) || string.IsNullOrEmpty(loginBody.Password)) { return Failed("用户名或密码不能为空"); } // 验证码校验 var captchaOnOff = (await _sysConfigService.QueryAsync(x => x.ConfigKey == SysConst.KEY_OFF_CAPTCHA)).FirstOrDefault(); if (captchaOnOff.ConfigValue == "true") { if (!loginBody.Code.IsNotEmptyOrNull()) { return Failed("验证码错误"); } var code = CookieHelper.GetCookies(HttpContext, CacheKey.Captcha); if (loginBody.Code.ToLower() != code.ToLower()) { return Failed("验证码错误"); } } loginBody.Password = MD5Helper.MD5Encrypt32(loginBody.Password); var user = (await _sysUserService.QueryAsync(d => d.LoginName == loginBody.LoginName && d.Password == loginBody.Password && d.DelFlag == false && d.Status == SysConst.ENABLE)).FirstOrDefault(); if (user.IsNotEmptyOrNull()) { var userRoles = await _sysUserService.GetUserRoleNameStr(loginBody.LoginName, loginBody.Password); //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 var claims = new List { new Claim(ClaimTypes.Name, user.LoginName.ToString()), new Claim(ClaimTypes.Sid, user.UserID.ToString()), new Claim(JwtRegisteredClaimNames.Jti, user.UserID.ToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); //记录登录信息 await RecordLoginInfo(user); return Success(token, "获取成功"); } else { user = (await _sysUserService.QueryAsync(d => d.LoginName == loginBody.LoginName && d.DelFlag == false)).FirstOrDefault(); if (user == null) { return Failed("用户不存在"); } user = (await _sysUserService.QueryAsync(d => d.LoginName == loginBody.LoginName && d.DelFlag == false && d.Status == SysConst.DISABLE)).FirstOrDefault(); if (user != null) { return Failed("用户处于禁用状态"); } return Failed("用户名或密码错误"); } } /// /// 默认使用管理员账号登录获取Token-JWT /// /// [HttpGet] [Route("LoginAdmin")] [AllowAnonymous] public async Task> GetJwtTokenAdmin() { // 是否开启测试环境 var isTestCurrent = Appsettings.app(new string[] { "AppSettings", "UseLoadTest" }).ObjToBool(); if (!isTestCurrent) return Failed("测试环境未开启"); string jwtStr = string.Empty; //管理员账号信息 string loginName = "admin"; string password = "Password01!"; password = MD5Helper.MD5Encrypt32(password); var user = (await _sysUserService.QueryAsync(d => d.LoginName == loginName && d.Password == password && d.DelFlag == false && d.Status == SysConst.ENABLE)).FirstOrDefault(); if (user.IsNotEmptyOrNull()) { var userRoles = await _sysUserService.GetUserRoleNameStr(loginName, password); //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 var claims = new List { new Claim(ClaimTypes.Name, user.LoginName.ToString()), new Claim(ClaimTypes.Sid, user.UserID.ToString()), new Claim(JwtRegisteredClaimNames.Jti, user.UserID.ToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); return Success(token, "获取成功"); } else { return Failed("认证失败"); } } /// /// 请求刷新Token(以旧换新) /// /// /// [HttpGet] [Route("RefreshToken")] [AllowAnonymous] public async Task> RefreshToken(string token = "") { string jwtStr = string.Empty; if (string.IsNullOrEmpty(token)) return Failed("token无效,请重新登录!"); var tokenModel = JwtHelper.SerializeJwt(token); if (tokenModel != null && tokenModel.Uid > 0) { var user = await _sysUserService.QueryByIdAsync(tokenModel.Uid); if (user != null) { var userRoles = await _sysUserService.GetUserRoleNameStr(user.LoginName, user.Password); //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 var claims = new List { new Claim(ClaimTypes.Name, tokenModel.Uid.ObjToString()), new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); //用户标识 var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); identity.AddClaims(claims); var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); return Success(refreshToken, "获取成功"); } } return Failed("认证失败!"); } /// /// 获取用户信息 /// /// 用户信息 [HttpGet] [Route("GetUserInfo")] public async Task> GetUserInfo() { UserPermission userPermission = new UserPermission() { SysUser = await _sysUserService.QueryByIdAsync(CurrentUser.UserID), Perms = await _sysPermissionService.GetMenuPermission(CurrentUser.UserID), Roles = await _sysPermissionService.GetRolePermission(CurrentUser.UserID) }; return Success(userPermission); } /// /// 获取路由信息 /// /// 路由信息 [HttpGet] [Route("GetRouters")] public async Task>> GetRouters() { var menus = await _sysMenuService.SelectMenuTreeByUserId(CurrentUser.UserID); return Success(_sysMenuService.BuildMenus(menus)); } /// /// 生成验证码 /// /// /// [HttpGet] [Route("Captcha")] [AllowAnonymous] public async Task Captcha() { var code = await _captcha.GenerateRandomCaptcha(); var result = await _captcha.GenerateCaptchaImage(code); // 将验证码的token放入cookie CookieHelper.SetCookies(HttpContext, CacheKey.Captcha, code); return File(result.CaptchaMemoryStream.ToArray(), "image/png"); } /// /// 退出登录 /// /// /// [HttpPost] [Route("Logout")] [AllowAnonymous] public MessageModel Logout(string token = "") { var refresh = RefreshToken(token).Result; return Success(refresh.data.IsNotEmptyOrNull() && refresh.data.token.IsNotEmptyOrNull()); } /// /// 用户注册 /// /// /// [HttpPost] [Route("Register")] [AllowAnonymous] public async Task> Register([FromBody] SysUser user) { MessageModel model = new MessageModel(); if (await _sysUserService.CheckLoginNameUnique(user.LoginName)) { model.success = false; model.msg = "登录账号已存在!"; return model; } user.Password = MD5Helper.MD5Encrypt32(user.Password); user.UserType = "00"; user.DelFlag = false; user.CreateTime = DateTime.Now; user.UpdateTime = DateTime.Now; user.CreateBy = user.LoginName; user.UpdateBy = user.LoginName; user.Status = SysConst.ENABLE; user.Sex = 0; return Success(await _sysUserService.AddAsync(user) > 0); } /// /// 记录登录信息 /// /// [NonAction] public async Task RecordLoginInfo(SysUser user) { user.LoginIP = IpHelper.GetIpAddr(HttpContext); user.LoginDate = DateTime.Now; await _sysUserService.UpdateAsync(user); var agent = HttpContext.Request.Headers["User-Agent"].ObjToString(); var parser = Parser.GetDefault(); var info = parser.Parse(agent); SysLoginInfo loginInfo = new SysLoginInfo() { UserName = user.LoginName, IPAddr = user.LoginIP, LoginLocation = AddressHelper.GetRealAddressByIP(user.LoginIP), Browser = info.UA.Family, OS = info.OS.Family, Status = SysConst.SUCCESS, Msg = user.UserName, LoginTime = DateTime.Now }; await _sysLoginInfoService.AddAsync(loginInfo); } } }