diff --git a/CoreCms.Net.Model/FromBody/FMWxPost.cs b/CoreCms.Net.Model/FromBody/FMWxPost.cs index 078de9ef..981e125c 100644 --- a/CoreCms.Net.Model/FromBody/FMWxPost.cs +++ b/CoreCms.Net.Model/FromBody/FMWxPost.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using CoreCms.Net.Model.Entities; namespace CoreCms.Net.Model.FromBody @@ -20,8 +21,9 @@ namespace CoreCms.Net.Model.FromBody public class FMWxPost { /// - /// 页面编码 + /// 用户前端编码 /// + [Required(ErrorMessage = "请提交合法数据")] public string code { get; set; } } diff --git a/CoreCms.Net.Web.WebApi/Controllers/UserController.cs b/CoreCms.Net.Web.WebApi/Controllers/UserController.cs index cb0ffa1b..e69e57e0 100644 --- a/CoreCms.Net.Web.WebApi/Controllers/UserController.cs +++ b/CoreCms.Net.Web.WebApi/Controllers/UserController.cs @@ -20,6 +20,7 @@ using System.Threading.Tasks; using CoreCms.Net.Auth.HttpContextUser; using CoreCms.Net.Auth.Policys; using CoreCms.Net.Caching.AccressToken; +using CoreCms.Net.Caching.AutoMate.RedisCache; using CoreCms.Net.Configuration; using CoreCms.Net.IServices; using CoreCms.Net.Loging; @@ -35,6 +36,7 @@ using CoreCms.Net.WeChat.Service.HttpClients; using CoreCms.Net.WeChat.Service.Models; using CoreCms.Net.WeChat.Service.Options; using CoreCms.Net.WeChat.Service.Utilities; +using DotLiquid.Util; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -87,11 +89,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers private readonly ICoreCmsOrderServices _orderServices; private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory; private readonly WeChatOptions _weChatOptions; - - - private readonly AsyncLock _mutex = new AsyncLock(); - - + private readonly IRedisOperationRepository _redisOperationRepository; /// /// 构造函数 @@ -122,7 +120,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers , ICoreCmsSettingServices settingServices , ICoreCmsServicesServices servicesServices , IOptions weChatOptions - , ICoreCmsUserServicesOrderServices userServicesOrderServices, ICoreCmsUserServicesTicketServices userServicesTicketServices, ICoreCmsStoreServices storeServices, ICoreCmsCouponServices couponServices, ICoreCmsOrderServices orderServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory) + , ICoreCmsUserServicesOrderServices userServicesOrderServices, ICoreCmsUserServicesTicketServices userServicesTicketServices, ICoreCmsStoreServices storeServices, ICoreCmsCouponServices couponServices, ICoreCmsOrderServices orderServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IRedisOperationRepository redisOperationRepository) { _user = user; _userWeChatInfoServices = userWeChatInfoServices; @@ -154,6 +152,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers _couponServices = couponServices; _orderServices = orderServices; _weChatApiHttpClientFactory = weChatApiHttpClientFactory; + _redisOperationRepository = redisOperationRepository; _weChatOptions = weChatOptions.Value; } @@ -170,86 +169,111 @@ namespace CoreCms.Net.Web.WebApi.Controllers { var jm = new WebApiCallBack(); - var client = _weChatApiHttpClientFactory.CreateWxOpenClient(); - var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken(); - var request = new SnsJsCode2SessionRequest(); - request.JsCode = entity.code; - request.AccessToken = accessToken; - - var response = await client.ExecuteSnsJsCode2SessionAsync(request, HttpContext.RequestAborted); - if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.请求成功) + var lockKey = "LOCK_OnLogin:user_" + entity.code; + var lockHolder = Guid.NewGuid().ToString("N"); //锁持有者 + var redisUserLock = await _redisOperationRepository.LockTakeAsync(lockKey, lockHolder, TimeSpan.FromSeconds(10)); + if (redisUserLock) { - using (await _mutex.LockAsync()) + try { - var userInfo = await _userWeChatInfoServices.QueryByClauseAsync(p => p.openid == response.OpenId); - if (userInfo == null) + var client = _weChatApiHttpClientFactory.CreateWxOpenClient(); + var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken(); + var request = new SnsJsCode2SessionRequest { - userInfo = new CoreCmsUserWeChatInfo(); - userInfo.openid = response.OpenId; - userInfo.type = (int)GlobalEnumVars.UserAccountTypes.微信小程序; - userInfo.sessionKey = response.SessionKey; - userInfo.gender = 1; - userInfo.createTime = DateTime.Now; - userInfo.unionId = response.UnionId; - await _userWeChatInfoServices.InsertAsync(userInfo); - } - else - { - if (userInfo.sessionKey != response.SessionKey) - { - await _userWeChatInfoServices.UpdateAsync( - p => new CoreCmsUserWeChatInfo() { sessionKey = response.SessionKey, updateTime = DateTime.Now }, - p => p.openid == userInfo.openid); - } - } + JsCode = entity.code, + AccessToken = accessToken + }; - if (userInfo is { userId: > 0 }) + var response = await client.ExecuteSnsJsCode2SessionAsync(request, HttpContext.RequestAborted); + if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.请求成功) { - var user = await _userServices.QueryByClauseAsync(p => p.id == userInfo.userId); - if (user != null) + var userInfo = await _userWeChatInfoServices.QueryByClauseAsync(p => p.openid == response.OpenId); + if (userInfo == null) { - var claims = new List { + userInfo = new CoreCmsUserWeChatInfo + { + openid = response.OpenId, + type = (int)GlobalEnumVars.UserAccountTypes.微信小程序, + sessionKey = response.SessionKey, + gender = 1, + createTime = DateTime.Now, + unionId = response.UnionId + }; + await _userWeChatInfoServices.InsertAsync(userInfo); + } + else + { + if (userInfo.sessionKey != response.SessionKey) + { + await _userWeChatInfoServices.UpdateAsync( + p => new CoreCmsUserWeChatInfo() { sessionKey = response.SessionKey, updateTime = DateTime.Now }, + p => p.openid == userInfo.openid); + } + } + + if (userInfo is { userId: > 0 }) + { + var user = await _userServices.QueryByClauseAsync(p => p.id == userInfo.userId); + if (user != null) + { + var claims = new List { new Claim(ClaimTypes.Name, user.nickName), new Claim(JwtRegisteredClaimNames.Jti, user.id.ToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_permissionRequirement.Expiration.TotalSeconds).ToString(CultureInfo.InvariantCulture)) }; - //用户标识 - var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); - identity.AddClaims(claims); - jm.status = true; - jm.data = new - { - auth = JwtToken.BuildJwtToken(claims.ToArray(), _permissionRequirement), - user - }; - jm.otherData = response.OpenId; + //用户标识 + var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); + identity.AddClaims(claims); + jm.status = true; + jm.data = new + { + auth = JwtToken.BuildJwtToken(claims.ToArray(), _permissionRequirement), + user + }; + jm.otherData = response.OpenId; - //录入登录日志 - var log = new CoreCmsUserLog(); - log.userId = user.id; - log.state = (int)GlobalEnumVars.UserLogTypes.登录; - log.ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1"; - log.createTime = DateTime.Now; - log.parameters = GlobalEnumVars.UserLogTypes.登录.ToString(); - await _userLogServices.InsertAsync(log); + //录入登录日志 + var log = new CoreCmsUserLog + { + userId = user.id, + state = (int)GlobalEnumVars.UserLogTypes.登录, + ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1", + createTime = DateTime.Now, + parameters = GlobalEnumVars.UserLogTypes.登录.ToString() + }; + await _userLogServices.InsertAsync(log); - return jm; + return jm; + } } + //注意:生产环境下SessionKey属于敏感信息,不能进行传输! + //return new JsonResult(new { success = true, msg = "OK", sessionAuthId = sessionBag.Key, sessionKey = sessionBag.SessionKey, data = jsonResult, sessionBag = sessionBag }); + jm.status = true; + jm.data = response.OpenId; + jm.otherData = response.OpenId; + //jm.methodDescription = JsonConvert.SerializeObject(sessionBag); + jm.msg = "OK"; + } + else + { + jm.msg = response.ErrorMessage; } } - //注意:生产环境下SessionKey属于敏感信息,不能进行传输! - //return new JsonResult(new { success = true, msg = "OK", sessionAuthId = sessionBag.Key, sessionKey = sessionBag.SessionKey, data = jsonResult, sessionBag = sessionBag }); - jm.status = true; - jm.data = response.OpenId; - jm.otherData = response.OpenId; - //jm.methodDescription = JsonConvert.SerializeObject(sessionBag); - jm.msg = "OK"; + catch (Exception e) + { + jm.msg = "数据处理异常"; + jm.otherData = e; + } + finally + { + await _redisOperationRepository.LockReleaseAsync(lockKey, lockHolder); + } } else { - jm.msg = response.ErrorMessage; + jm.msg = "当前请求太频繁_请稍后再试"; } - + return jm; } #endregion