AuthService.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. using Furion.DataEncryption;
  2. using Furion.DependencyInjection;
  3. using Furion.DynamicApiController;
  4. using Furion.EventBus;
  5. using Furion.FriendlyException;
  6. using Microsoft.AspNetCore.Authorization;
  7. using Microsoft.AspNetCore.Http;
  8. using Microsoft.AspNetCore.Mvc;
  9. using Microsoft.Extensions.Options;
  10. using System.Collections.Generic;
  11. using System.ComponentModel.DataAnnotations;
  12. using System.Linq;
  13. using System.Threading.Tasks;
  14. using UAParser;
  15. namespace Admin.NET.Core.Service
  16. {
  17. /// <summary>
  18. /// 系统登录授权服务
  19. /// </summary>
  20. [ApiDescriptionSettings(Name = "登录授权", Order = 200)]
  21. public class AuthService : IDynamicApiController, ITransient
  22. {
  23. private readonly SqlSugarRepository<SysUser> _sysUserRep;
  24. private readonly RefreshTokenOptions _refreshTokenOptions;
  25. private readonly IHttpContextAccessor _httpContextAccessor;
  26. private readonly IUserManager _userManager;
  27. private readonly IEventPublisher _eventPublisher;
  28. private readonly SysUserService _sysUserService;
  29. private readonly SysUserRoleService _sysUserRoleService;
  30. public AuthService(SqlSugarRepository<SysUser> sysUserRep,
  31. IOptions<RefreshTokenOptions> refreshTokenOptions,
  32. IHttpContextAccessor httpContextAccessor,
  33. IUserManager userManager,
  34. IEventPublisher eventPublisher,
  35. SysUserService sysUserService,
  36. SysUserRoleService sysUserRoleService)
  37. {
  38. _sysUserRep = sysUserRep;
  39. _httpContextAccessor = httpContextAccessor;
  40. _userManager = userManager;
  41. _refreshTokenOptions = refreshTokenOptions.Value;
  42. _eventPublisher = eventPublisher;
  43. _sysUserService = sysUserService;
  44. _sysUserRoleService = sysUserRoleService;
  45. }
  46. /// <summary>
  47. /// 登录系统
  48. /// </summary>
  49. /// <param name="input"></param>
  50. /// <remarks>用户名/密码:admin/123456</remarks>
  51. /// <returns></returns>
  52. [HttpPost("/login")]
  53. [AllowAnonymous]
  54. public async Task<LoginOutput> Login([Required] LoginInput input)
  55. {
  56. var encryptPasswod = MD5Encryption.Encrypt(input.Password); // 加密密码
  57. // 判断用户名密码
  58. var user = await _sysUserRep.AsQueryable().Includes(u => u.SysOrg)
  59. .FirstAsync(u => u.UserName.Equals(input.UserName) && u.Password.Equals(encryptPasswod));
  60. _ = user ?? throw Oops.Oh(ErrorCodeEnum.D1000);
  61. // 验证账号是否被冻结
  62. if (user.Status == StatusEnum.Disable)
  63. throw Oops.Oh(ErrorCodeEnum.D1017);
  64. // 生成Token令牌
  65. var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
  66. {
  67. {ClaimConst.UserId, user.Id},
  68. {ClaimConst.TenantId, user.TenantId},
  69. {ClaimConst.UserName, user.UserName},
  70. {ClaimConst.RealName, user.RealName},
  71. {ClaimConst.SuperAdmin, user.UserType},
  72. {ClaimConst.OrgId, user.OrgId},
  73. {ClaimConst.OrgName, user.SysOrg?.Name},
  74. });
  75. // 设置Swagger自动登录
  76. _httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
  77. // 生成刷新Token令牌
  78. var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, _refreshTokenOptions.ExpiredTime);
  79. // 设置刷新Token令牌
  80. _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
  81. return new LoginOutput
  82. {
  83. UserId = user.Id,
  84. Token = accessToken
  85. };
  86. }
  87. /// <summary>
  88. /// 获取用户信息
  89. /// </summary>
  90. /// <returns></returns>
  91. [HttpGet("/getUserInfo")]
  92. public async Task<LoginUserInfoOutput> GetUserInfo()
  93. {
  94. var user = _userManager.User;
  95. if (user == null)
  96. throw Oops.Oh(ErrorCodeEnum.D1011);
  97. // 角色信息
  98. var roles = await _sysUserRoleService.GetUserRoleList(user.Id);
  99. // 数据范围
  100. var dataScopes = await _sysUserService.GetUserOrgIdList();
  101. // 增加登录日志
  102. var client = Parser.GetDefault().Parse(_httpContextAccessor.HttpContext.Request.Headers["User-Agent"]);
  103. await _eventPublisher.PublishAsync(new ChannelEventSource("Add:VisLog",
  104. new SysLogVis
  105. {
  106. Success = YesNoEnum.Y,
  107. Message = "登录",
  108. Ip = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(),
  109. Browser = client.UA.Family + client.UA.Major,
  110. Os = client.OS.Family + client.OS.Major,
  111. VisType = LoginTypeEnum.Login,
  112. UserName = user.UserName,
  113. RealName = user.RealName
  114. }));
  115. return new LoginUserInfoOutput
  116. {
  117. UserId = user.Id,
  118. Username = user.UserName,
  119. RealName = user.RealName,
  120. Avatar = user.Avatar,
  121. Desc = user.Introduction,
  122. Roles = roles.Select(u => new LoginRole
  123. {
  124. RoleName = u.Name,
  125. Value = u.Code
  126. }).ToList(),
  127. };
  128. }
  129. /// <summary>
  130. /// 获取刷新Token
  131. /// </summary>
  132. /// <param name="accessToken"></param>
  133. /// <returns></returns>
  134. [HttpPost("/getRefreshToken")]
  135. public string RefreshToken([Required] string accessToken)
  136. {
  137. return JWTEncryption.GenerateRefreshToken(accessToken, _refreshTokenOptions.ExpiredTime);
  138. }
  139. /// <summary>
  140. /// 退出系统
  141. /// </summary>
  142. [HttpGet("/logout")]
  143. public async void Logout()
  144. {
  145. var user = _userManager.User;
  146. if (user == null)
  147. throw Oops.Oh(ErrorCodeEnum.D1011);
  148. // 退出Swagger
  149. _httpContextAccessor.HttpContext.SignoutToSwagger();
  150. //_httpContextAccessor.HttpContext.Response.Headers["access-token"] = "invalid token";
  151. // 增加退出日志
  152. await _eventPublisher.PublishAsync(new ChannelEventSource("Add:VisLog",
  153. new SysLogVis
  154. {
  155. Success = YesNoEnum.Y,
  156. Message = "退出",
  157. VisType = LoginTypeEnum.Logout,
  158. Ip = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(),
  159. UserName = user.UserName,
  160. RealName = user.RealName
  161. }));
  162. }
  163. }
  164. }