using HiTeachCC.Library.Common; using HiTeachCC.Model.Core.Dtos; using HiTeachCC.Model.Core.Models; using HiTeachCC.Service.Core.Interface; using IdentityModel; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using TEAMModelOS.SDK.Context.Configuration; using TEAMModelOS.SDK.Context.Constant.Common; using TEAMModelOS.SDK.Context.Exception; using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest; using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse; using TEAMModelOS.SDK.Extension.HttpClient.Implements; using TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper; using TEAMModelOS.SDK.Extension.JwtAuth.Models; using TEAMModelOS.SDK.Helper.Common.DateTimeHelper; using TEAMModelOS.SDK.Helper.Common.JsonHelper; using TEAMModelOS.SDK.Helper.Network.HttpHelper; using TEAMModelOS.SDK.Helper.Security.BCryptHelper; namespace HiTeachCC.Service.Core.Implement { public class LoginInfoService : BaseService, ILoginInfoService { private readonly HttpClientUserInfo _httpClientService; public LoginInfoService(HttpClientUserInfo httpClientUserInfo) { _httpClientService = httpClientUserInfo; } public async Task VerifyWeChat(Dictionary dict) { if (dict.TryGetValue("code", out object code)) { WeChatToken oauth2Token = await GetWeChatAccessToken(code!=null?code.ToString():""); oauth2Token.RowKey = oauth2Token.access_token; oauth2Token.PartitionKey = "WeChatOauth2Token"; oauth2Token = await SaveOrUpdate(oauth2Token); } return null; } /// /// 获取微信AccessToken /// /// /// private async Task GetWeChatAccessTokenClient() { string requestUrl = BaseConfigModel.Configuration["HaBookAuth:WeChatAccessTokenUrlClient"] + "appid={{APPID}}&secret={{SECRET}}&code={{CODE}}&grant_type=client_credential"; requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["HaBookAuth:WeChatAppID"]); requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["HaBookAuth:WeChatAppSecret"]); string info = await HttpHelper.HttpGetAsync(requestUrl); return MessagePackHelper.JsonToObject(info); } /// /// 获取微信AccessToken /// /// /// private async Task GetWeChatAccessToken(string Code ) { if (string.IsNullOrEmpty(Code)) { return null; } string requestUrl = BaseConfigModel.Configuration["HaBookAuth:WeChatAccessTokenUrlCode"] + "appid={{APPID}}&secret={{SECRET}}&code={{CODE}}&grant_type=authorization_code"; requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["HaBookAuth:WeChatAppID"]); requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["HaBookAuth:WeChatAppSecret"]); requestUrl = requestUrl.Replace("{{CODE}}", Code); string info= await HttpHelper.HttpGetAsync(requestUrl); return MessagePackHelper.JsonToObject(info); } /// /// 获取微信登录跳转链接 /// /// 13位时间戳 /// public Dictionary GetWechatConfig(string Time) { Dictionary config = new Dictionary(); config.Add("WeChatAuthorizeUrlCode", BaseConfigModel.Configuration["HaBookAuth:WeChatAuthorizeUrlCode"] + "?appid="+ BaseConfigModel.Configuration["HaBookAuth:WeChatAppID"] + "&redirect_uri={{redirect_uri}}&response_type=code&scope=snsapi_userinfo&state="+ Time + "#wechat_redirect"); return config; } public async Task VerifyMiniAPP(Dictionary dict) { MiniAPPLoginInfo loginInfo = null ; if (dict.TryGetValue("js_code", out object js_code)) { if (string.IsNullOrEmpty(js_code != null ? js_code.ToString() : "")) { throw new Exception( "Validation failure , js_code is null!"); } string requestUrl = BaseConfigModel.Configuration["HaBookAuth:MiniAPPAuthUrl"]; requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["HaBookAuth:MiniAPPID"]); requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["HaBookAuth:MiniAPPSECRET"]); requestUrl = requestUrl.Replace("{{JSCODE}}", js_code.ToString()); string info = await HttpHelper.HttpGetAsync(requestUrl); loginInfo = MessagePackHelper.JsonToObject(info); if (loginInfo != null) { if (loginInfo.errcode != 0) { throw new Exception( loginInfo.errmsg); } } else { throw new Exception( "Validation failure , loginInfo is null !"); } } else { throw new Exception( "js_code is null !"); } return loginInfo; } /// /// 获取微信AccessToken /// /// /// public async Task GetMiniAPPAccessToken() { string requestUrl = BaseConfigModel.Configuration["HaBookAuth:MiniAPPAccessTokenUrl"]; requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["HaBookAuth:MiniAPPID"]); requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["HaBookAuth:MiniAPPSECRET"]); string info = await HttpHelper.HttpGetAsync(requestUrl); MiniAPPToken miniAPPToken= MessagePackHelper.JsonToObject(info); if (miniAPPToken != null) { if (miniAPPToken.errcode != 0) { throw new Exception( miniAPPToken.errmsg); } } else { throw new Exception( "Validation failure,miniAPPToken is null!"); } return miniAPPToken; } /// /// 获取用户登录信息 /// /// /// /// public async Task GetWeChatUserInfo(string session_key ,Dictionary dict) { string enData = ""; if (dict.TryGetValue("encryptedData", out object encryptedData) && dict.TryGetValue("iv", out object iv)) { if (encryptedData != null && iv != null) { /** *{"openId":"oLaYK45lBS8HWSAXJisDdIlEWj3A", * "nickName":"菁華浮梦、℡", * "gender":1, * "language":"zh_CN", * "city":"Chengdu", * "province":"Sichuan", * "country":"China", * "avatarUrl":"https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83er98z4MsFd1xKML71TwQuR1Bxnt7ib3SGrNsKiaBCLYbLeS7KAT8h0ia8byiaVzurvEpVmmQpSzBQs5Nw/132", * "unionId":"oqADO5qdTR6PItxhmDEPCsWU9PqI", * "watermark":{"timestamp":1562224447,"appid":"wxf4905703824211aa"}} **/ enData = WeChatCryptHelper.AESDecrypt(encryptedData.ToString(),session_key,iv.ToString()); } } //string requestUrl = BaseConfigModel.Configuration["HaBookAuth:UnionidUserinfo"]; //requestUrl = requestUrl.Replace("{{openid}}", unionid); //WeChatToken weChatToken = await GetWeChatAccessTokenClient(); //requestUrl = requestUrl.Replace("{{access_token}}", weChatToken.access_token); //string info = await HttpHelper.HttpGetAsync(requestUrl); MiniAPPUserInfo miniAPPUser = MessagePackHelper.JsonToObject(enData); if (miniAPPUser != null) { WeChatUser weChatUser = new WeChatUser(); weChatUser.RowKey = miniAPPUser.unionId; weChatUser.PartitionKey = miniAPPUser.country; weChatUser.nickName = miniAPPUser.nickName; weChatUser.gender = miniAPPUser.gender; weChatUser.avatarUrl = miniAPPUser.avatarUrl; weChatUser.country = miniAPPUser.country; weChatUser.city = miniAPPUser.city; weChatUser.province = miniAPPUser.province; weChatUser.openId = miniAPPUser.openId; weChatUser.unionId = miniAPPUser.unionId; weChatUser.appid = miniAPPUser.watermark.appid; await SaveOrUpdate(weChatUser); return weChatUser; } else { throw new Exception( "Validation failure,miniAPPToken is null!"); } } public async Task MiniAPPLogin(Dictionary dict) { MiniAPPLoginInfo loginInfo= await VerifyMiniAPP(dict); WeChatUser weChatUser = await GetWeChatUserInfo(loginInfo.session_key , dict); JwtResponse jwt= CreateJwtToken(weChatUser); LoginInfo login = new LoginInfo(); login.RowKey = Guid.NewGuid().ToString(); login.PartitionKey = weChatUser.PartitionKey; login.TeamModelId = weChatUser.unionId; login.Token = jwt.Access_token; login.Scope = jwt.Scope; return jwt; } public JwtResponse CreateJwtToken(WeChatUser user) { ClaimModel model = new ClaimModel { Scope = "MiniAPP" }; if (user!=null ) { model.Claims.Add(new Claim(JwtClaimTypes.Name, user.nickName)); model.Claims.Add(new Claim(JwtClaimTypes.Id, user.unionId)); model.Claims.AddRange("Student".Split(',').Select(s => new Claim(JwtClaimTypes.Role, s))); model.Roles.Add("Student"); JwtResponse jwtResponse = JwtHelper.IssueJWT(model, BaseConfigModel.Configuration.GetSection("JwtSetting").Get()); return jwtResponse; } else { throw new Exception( "Validation failure,user is null !"); } } public JwtResponse CreateJwtToken(LoginInfo login) { ClaimModel model = new ClaimModel { Scope = "WebAPP" }; if (login != null) { model.Claims.Add(new Claim(JwtClaimTypes.Name, login.Name)); model.Claims.Add(new Claim(JwtClaimTypes.Id, login.TeamModelId)); model.Claims.AddRange("Student".Split(',').Select(s => new Claim(JwtClaimTypes.Role, s))); model.Roles.Add("Teacher"); JwtResponse jwtResponse = JwtHelper.IssueJWT(model, BaseConfigModel.Configuration.GetSection("JwtSetting").Get()); return jwtResponse; } else { throw new Exception("Validation failure,user is null !"); } } public async Task TeamModelLogin(TicketInfo ticketInfo) { if (string.IsNullOrEmpty(ticketInfo.Token)) { if (string.IsNullOrEmpty(ticketInfo.Ticket)) { throw new BizException(401, "Unauthorized"); } string code = BCryptHelper.Ecrypt(ticketInfo.Ticket + ticketInfo.TeamModelId); bool f = BCryptHelper.Verify(ticketInfo.Ticket + ticketInfo.TeamModelId, ticketInfo.Sign); LoginInfo login = FindOneByKey("Ticket", ticketInfo.Ticket).Result; if (login != null && !string.IsNullOrEmpty(login.Token)) { JwtResponse token = CreateJwtToken(login); login.Token = token.Access_token; await Update(login); return token; } ///不验证TmdID #region /* LoginInfo loginInfo = new LoginInfo { PartitionKey = "15283771540", Phone = "15283771540", RowKey = Guid.NewGuid().ToString(), TeamModelId = ticketInfo.TeamModelId, Name = ticketInfo.Name, Ticket = ticketInfo.Ticket, CountryCode = "86" }; TeamModelUser user = await FindOneByKey("TeamModelId", ticketInfo.TeamModelId); if (user == null || string.IsNullOrEmpty(user.RowKey)) { user = new TeamModelUser { RowKey = Guid.NewGuid().ToString(), PartitionKey = loginInfo.CountryCode, registerTime = DateTimeHelper.ConvertToTimeStamp13(DateTime.Now) }; } user.cellphone = "15283771540"; user.nickname = ticketInfo.Name; if (string.IsNullOrEmpty(user.fullName)) { user.fullName = ticketInfo.Name; } user.teamModelId = ticketInfo.TeamModelId; user.phoneCode = "86"; JwtResponse jwtToken = CreateJwtToken(loginInfo); loginInfo.Token = jwtToken.Access_token; loginInfo.Scope = jwtToken.Scope; await Save(loginInfo); await SaveOrUpdate(user); return jwtToken; */ #endregion JosnRPCRequest> request = new JosnRPCRequest> { method = "UserInfo" }; Dictionary ticket = new Dictionary { { "ticket", ticketInfo.Ticket } }; request.@params = ticket; string data = MessagePackHelper.ObjectToJson(request); string jsonStr = _httpClientService.HttpPost(BaseConfigModel.Configuration["HaBookAuth:AccountUrl"], data, Constants.CONTENT_TYPE_JSON, Encoding.UTF8); if (!string.IsNullOrEmpty(jsonStr)) { JosnRPCResponse response = MessagePackHelper.JsonToObject>(jsonStr); if (response.error == null && response != null) { LoginInfo loginInfo = new LoginInfo { PartitionKey = response.result.cellphone, Phone = response.result.cellphone, RowKey = Guid.NewGuid().ToString(), TeamModelId = response.result.id, Name = response.result.name, Ticket = ticketInfo.Ticket, CountryCode = response.result.countryCode }; TeamModelUser user= await FindOneByKey("TeamModelId", response.result.id); if (user == null || string.IsNullOrEmpty(user.RowKey)) { user = new TeamModelUser { RowKey = Guid.NewGuid().ToString(), PartitionKey = loginInfo.CountryCode ,registerTime=DateTimeHelper.ConvertToTimeStamp13(DateTime.Now) }; } user.cellphone = response.result.cellphone; user.nickName = response.result.name; if (string.IsNullOrEmpty(user.fullName)) { user.fullName = response.result.name; } user.teamModelId = response.result.id; user.phoneCode = response.result.countryCode; JwtResponse jwtToken = CreateJwtToken(loginInfo); loginInfo.Token = jwtToken.Access_token; loginInfo.Scope = jwtToken.Scope; await Save(loginInfo); await SaveOrUpdate(user); return jwtToken; } else { throw new BizException(401, "Unauthorized"); } } else { throw new BizException(401, "Unauthorized"); } } else { ClaimModel claimModel = JwtHelper.SerializeJWT(ticketInfo.Token); var dateTime = DateTimeHelper.ConvertToTimeStamp10(DateTime.Now); var expExt = claimModel.Claim.TryGetValue("exp", out var exp); if (expExt == false || dateTime > long.Parse(exp.ToString())) { throw new BizException(401, "Unauthorized"); } Dictionary msp = new Dictionary { { "Token", ticketInfo.Token } }; LoginInfo loginInfo = FindOneByDict(msp).Result; if (loginInfo != null && !string.IsNullOrEmpty(loginInfo.Token)) { return new JwtResponse { Access_token = loginInfo.Token, Scope = loginInfo.Scope }; } else { throw new BizException(401, "Unauthorized"); } } } } }