LoginHelper.cs 6.0 KB

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