AuthController.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using System.Security.Claims;
  5. using System.Threading.Tasks;
  6. using Microsoft.AspNetCore.Authorization;
  7. using Microsoft.AspNetCore.Cors;
  8. using Microsoft.AspNetCore.Mvc;
  9. using Microsoft.AspNetCore.Mvc.ModelBinding;
  10. using ZhonTai.Plate.Admin.HttpApi.Shared.Attributes;
  11. using ZhonTai.Common.Auth;
  12. using ZhonTai.Common.Consts;
  13. using ZhonTai.Common.Extensions;
  14. using ZhonTai.Common.Domain.Dto;
  15. using ZhonTai.Plate.Admin.Service.Auth;
  16. using ZhonTai.Plate.Admin.Service.Auth.Dto;
  17. using ZhonTai.Plate.Admin.Service.LoginLog;
  18. using ZhonTai.Plate.Admin.Service.LoginLog.Dto;
  19. using ZhonTai.Plate.Admin.Service.User;
  20. using ZhonTai.Tools.Captcha;
  21. using ZhonTai.Plate.Admin.Service.Contracts;
  22. using StackExchange.Profiling;
  23. namespace ZhonTai.Plate.Admin.HttpApi
  24. {
  25. /// <summary>
  26. /// 授权管理
  27. /// </summary>
  28. public class AuthController : AreaController
  29. {
  30. private readonly IUserToken _userToken;
  31. private readonly IAuthService _authService;
  32. private readonly IUserService _userService;
  33. private readonly ILoginLogService _loginLogService;
  34. private readonly ICaptchaTool _captcha;
  35. public AuthController(
  36. IUserToken userToken,
  37. IAuthService authService,
  38. IUserService userService,
  39. ILoginLogService loginLogService,
  40. ICaptchaTool captcha
  41. )
  42. {
  43. _userToken = userToken;
  44. _authService = authService;
  45. _userService = userService;
  46. _loginLogService = loginLogService;
  47. _captcha = captcha;
  48. }
  49. /// <summary>
  50. /// 获得token
  51. /// </summary>
  52. /// <param name="output"></param>
  53. /// <returns></returns>
  54. private IResultOutput GetToken(ResultOutput<AuthLoginOutput> output)
  55. {
  56. if (!output.Success)
  57. {
  58. return ResultOutput.NotOk(output.Msg);
  59. }
  60. var user = output.Data;
  61. if (user == null)
  62. {
  63. return ResultOutput.NotOk();
  64. }
  65. var token = _userToken.Create(new[]
  66. {
  67. new Claim(ClaimAttributes.UserId, user.Id.ToString()),
  68. new Claim(ClaimAttributes.UserName, user.UserName),
  69. new Claim(ClaimAttributes.UserNickName, user.NickName),
  70. new Claim(ClaimAttributes.TenantId, user.TenantId.ToString()),
  71. new Claim(ClaimAttributes.TenantType, user.TenantType.ToString()),
  72. new Claim(ClaimAttributes.DataIsolationType, user.DataIsolationType.ToString())
  73. });
  74. return ResultOutput.Ok(new { token });
  75. }
  76. /// <summary>
  77. /// 获取验证数据
  78. /// </summary>
  79. /// <returns></returns>
  80. [HttpGet]
  81. [AllowAnonymous]
  82. [NoOprationLog]
  83. [EnableCors(AdminConsts.AllowAnyPolicyName)]
  84. public async Task<IResultOutput> GetCaptcha()
  85. {
  86. using (MiniProfiler.Current.Step("获取滑块验证"))
  87. {
  88. var data = await _captcha.GetAsync(CacheKey.CaptchaKey);
  89. return ResultOutput.Ok(data);
  90. }
  91. }
  92. /// <summary>
  93. /// 检查验证数据
  94. /// </summary>
  95. /// <returns></returns>
  96. [HttpGet]
  97. [AllowAnonymous]
  98. [NoOprationLog]
  99. [EnableCors(AdminConsts.AllowAnyPolicyName)]
  100. public async Task<IResultOutput> CheckCaptcha([FromQuery] CaptchaInput input)
  101. {
  102. input.CaptchaKey = CacheKey.CaptchaKey;
  103. var result = await _captcha.CheckAsync(input);
  104. return ResultOutput.Result(result);
  105. }
  106. /// <summary>
  107. /// 获取密钥
  108. /// </summary>
  109. /// <returns></returns>
  110. [HttpGet]
  111. [AllowAnonymous]
  112. [NoOprationLog]
  113. public async Task<IResultOutput> GetPassWordEncryptKey()
  114. {
  115. return await _authService.GetPassWordEncryptKeyAsync();
  116. }
  117. /// <summary>
  118. /// 查询用户信息
  119. /// </summary>
  120. /// <returns></returns>
  121. [HttpGet]
  122. [Login]
  123. public async Task<IResultOutput> GetUserInfo()
  124. {
  125. return await _authService.GetUserInfoAsync();
  126. }
  127. /// <summary>
  128. /// 用户登录
  129. /// 根据登录信息生成Token
  130. /// </summary>
  131. /// <param name="input">登录信息</param>
  132. /// <returns></returns>
  133. [HttpPost]
  134. [AllowAnonymous]
  135. [NoOprationLog]
  136. public async Task<IResultOutput> Login(AuthLoginInput input)
  137. {
  138. var sw = new Stopwatch();
  139. sw.Start();
  140. var res = await _authService.LoginAsync(input);
  141. sw.Stop();
  142. #region 添加登录日志
  143. var loginLogAddInput = new LoginLogAddInput()
  144. {
  145. CreatedUserName = input.UserName,
  146. ElapsedMilliseconds = sw.ElapsedMilliseconds,
  147. Status = res.Success,
  148. Msg = res.Msg
  149. };
  150. ResultOutput<AuthLoginOutput> output = null;
  151. if (res.Success)
  152. {
  153. output = (res as ResultOutput<AuthLoginOutput>);
  154. var user = output.Data;
  155. loginLogAddInput.CreatedUserId = user.Id;
  156. loginLogAddInput.NickName = user.NickName;
  157. loginLogAddInput.TenantId = user.TenantId;
  158. }
  159. await _loginLogService.AddAsync(loginLogAddInput);
  160. #endregion 添加登录日志
  161. if (!res.Success)
  162. {
  163. return res;
  164. }
  165. return GetToken(output);
  166. }
  167. /// <summary>
  168. /// 刷新Token
  169. /// 以旧换新
  170. /// </summary>
  171. /// <param name="token"></param>
  172. /// <returns></returns>
  173. [HttpGet]
  174. [AllowAnonymous]
  175. public async Task<IResultOutput> Refresh([BindRequired] string token)
  176. {
  177. var userClaims = _userToken.Decode(token);
  178. if (userClaims == null || userClaims.Length == 0)
  179. {
  180. return ResultOutput.NotOk();
  181. }
  182. var refreshExpires = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.RefreshExpires)?.Value;
  183. if (refreshExpires.IsNull())
  184. {
  185. return ResultOutput.NotOk();
  186. }
  187. if (refreshExpires.ToLong() <= DateTime.Now.ToTimestamp())
  188. {
  189. return ResultOutput.NotOk("登录信息已过期");
  190. }
  191. var userId = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.UserId)?.Value;
  192. if (userId.IsNull())
  193. {
  194. return ResultOutput.NotOk("登录信息已失效");
  195. }
  196. var output = await _userService.GetLoginUserAsync(userId.ToLong());
  197. return GetToken(output);
  198. }
  199. }
  200. }