LoginHelper.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // <author></author>
  2. // <date></date>
  3. // <description></description>
  4. using ERP.Framework.Cache;
  5. using ERP.Framework.Config;
  6. using ERP.Framework.Constants;
  7. using ERP.Framework.Emum;
  8. using ERP.Framework.Exceptions;
  9. using ERP.Framework.Resource;
  10. using ERP.Framework.Security.Core;
  11. using ERP.Framework.Utils;
  12. using Microsoft.AspNetCore.Http;
  13. using Newtonsoft.Json;
  14. namespace ERP.Framework.Security
  15. {
  16. public class LoginHelper
  17. {
  18. /// <summary>
  19. /// 根据设备进行登录
  20. /// </summary>
  21. /// <param name="userInfo"></param>
  22. /// <param name="securityConfig"></param>
  23. /// <param name="device"></param>
  24. /// <param name="deviceKey"></param>
  25. /// <returns></returns>
  26. public static string LoginByDevice(
  27. LoginUser userInfo
  28. , SecurityConfig securityConfig
  29. , DeviceEnum device)
  30. {
  31. string tokenId;
  32. var tokenList = GetTokenList(userInfo.UserId);
  33. var result = TokenHelper.CreateToken(
  34. securityConfig.JwtSecurityKey
  35. , userInfo.UserId
  36. , userInfo.UserName
  37. , securityConfig.TimeOut
  38. , out tokenId);
  39. //Todo 不允许并发登录处理
  40. HandleExceedToken(tokenList, securityConfig);
  41. tokenList.Add(new TokenSign
  42. {
  43. TokenId = tokenId,
  44. Device = device
  45. });
  46. SetTokenList(userInfo.UserId, tokenList);
  47. SetLastActivity(tokenId, securityConfig.ActivityTimeOut, securityConfig.TimeOut);
  48. SetUserInfo(tokenId, userInfo, securityConfig.TimeOut);
  49. return result;
  50. }
  51. /// <summary>
  52. /// 获取当前用户
  53. /// </summary>
  54. /// <returns></returns>
  55. /// <exception cref="Exception"></exception>
  56. public static LoginUser GetLoginUser()
  57. {
  58. var httpContextAccessor = new HttpContextAccessor();
  59. var httpContext = httpContextAccessor.HttpContext;
  60. var loginUser = httpContext!.Items["LoginUser"] as LoginUser;
  61. if (loginUser != null)
  62. {
  63. return loginUser;
  64. }
  65. var tokenId = httpContext!.Items["TokenId"] as string;
  66. var redisData = RedisHelper.Get(AuthConstant.USER_INFO + tokenId);
  67. var result = JsonConvert.DeserializeObject<LoginUser>(redisData);
  68. if (result != null)
  69. {
  70. httpContext.Items["LoginUser"] = result;
  71. return result;
  72. }
  73. else
  74. {
  75. throw new CodeException(message: FrameworkI18N.NoUser, code: ErrorCode.NO_USER);
  76. }
  77. }
  78. /// <summary>
  79. /// 获取当前用户Id
  80. /// </summary>
  81. /// <returns></returns>
  82. public static long GetUserId()
  83. {
  84. var httpContextAccessor = new HttpContextAccessor();
  85. var httpContext = httpContextAccessor.HttpContext;
  86. var result = httpContext!.Items["UserId"] as string;
  87. return result!.ToLong()!.Value;
  88. }
  89. public static bool IsAdmin()
  90. {
  91. var httpContextAccessor = new HttpContextAccessor();
  92. var httpContext = httpContextAccessor.HttpContext;
  93. var userName = httpContext!.Items["UserName"] as string;
  94. return userName == FrameworkConstant.ADMIN;
  95. }
  96. /// <summary>
  97. /// 获取TokenList缓存
  98. /// </summary>
  99. /// <param name="userId"></param>
  100. /// <returns></returns>
  101. private static List<TokenSign> GetTokenList(long userId)
  102. {
  103. var tokenListData = RedisHelper.Get(AuthConstant.TOKEN_LIST + CryptoUtil.MD5(userId.ToString()));
  104. if (!tokenListData.IsNullOrEmpty())
  105. {
  106. var data = JsonConvert.DeserializeObject<List<TokenSign>>(tokenListData)!;
  107. return data;
  108. }
  109. return new List<TokenSign>();
  110. }
  111. /// <summary>
  112. /// 创建Last Activity
  113. /// </summary>
  114. /// <param name="tokenId"></param>
  115. /// <param name="activityTimeOut"></param>
  116. private static void SetLastActivity(string tokenId, int activityTimeOut, int tokenTimeOut)
  117. {
  118. var key = AuthConstant.LAST_ACTIVITY + tokenId;
  119. var val = DateTime.Now.AddMinutes(activityTimeOut).ToDateLongString();
  120. RedisHelper.SaveExpire(key, val, tokenTimeOut);
  121. }
  122. /// <summary>
  123. /// 处理超出的会话
  124. /// </summary>
  125. /// <param name="list"></param>
  126. /// <param name="maxCount"></param>
  127. private static void HandleExceedToken(List<TokenSign> list, SecurityConfig config)
  128. {
  129. if (list.Count > config.MaxLoginCount)
  130. {
  131. var num = list.Count - config.MaxLoginCount;
  132. var substituteList = list.Take(num).ToList();
  133. foreach (var item in substituteList)
  134. {
  135. SubstitutedUser(item.TokenId, config.TimeOut);
  136. }
  137. list.RemoveRange(0, num);
  138. }
  139. }
  140. /// <summary>
  141. /// 顶下用户
  142. /// </summary>
  143. /// <param name="tokenId"></param>
  144. /// <param name="activityTimeOut"></param>
  145. private static void SubstitutedUser(string tokenId, int tokenTimeOut)
  146. {
  147. var key = AuthConstant.LAST_ACTIVITY + tokenId;
  148. RedisHelper.SaveExpire(key, AuthConstant.SUBSTITUTED, tokenTimeOut);
  149. }
  150. /// <summary>
  151. /// 创建Token List缓存
  152. /// </summary>
  153. /// <param name="tokenId"></param>
  154. /// <param name="activityTimeOut"></param>
  155. private static void SetTokenList(long userId, List<TokenSign> list)
  156. {
  157. var key = AuthConstant.TOKEN_LIST + CryptoUtil.MD5(userId.ToString());
  158. var val = JsonConvert.SerializeObject(list);
  159. RedisHelper.Save(key, val);
  160. }
  161. /// <summary>
  162. /// 创建UserInfo
  163. /// </summary>
  164. /// <param name="tokenId"></param>
  165. /// <param name="activityTimeOut"></param>
  166. private static void SetUserInfo(string tokenId, LoginUser loginUser, int tokenTimeOut)
  167. {
  168. var key = AuthConstant.USER_INFO + tokenId;
  169. var val = JsonConvert.SerializeObject(loginUser);
  170. RedisHelper.SaveExpire(key, val, tokenTimeOut);
  171. }
  172. }
  173. }