WeChatService.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. using HiTeachCE.Extension;
  2. using HiTeachCE.Helpers;
  3. using HiTeachCE.Models;
  4. using IdentityModel;
  5. using Microsoft.Extensions.Configuration;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Linq.Expressions;
  10. using System.Security.Claims;
  11. using System.Threading.Tasks;
  12. using TEAMModelOS.SDK.Context.Configuration;
  13. using TEAMModelOS.SDK.Extension.JwtAuth.Models;
  14. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  15. using TEAMModelOS.SDK.Helper.Common.JsonHelper;
  16. using TEAMModelOS.SDK.Helper.Network.HttpHelper;
  17. using JwtSetting = HiTeachCE.Extension.JwtSetting;
  18. namespace HiTeachCE.Services
  19. {
  20. public class WeChatService : IBusinessService
  21. {
  22. public WeChatUserService weChatUserService;
  23. public WeChatService(WeChatUserService _weChatUserService) {
  24. weChatUserService = _weChatUserService;
  25. }
  26. public async Task<object> VerifyWeChat(Dictionary<string, object> dict)
  27. {
  28. if (dict.TryGetValue("code", out object code))
  29. {
  30. WeChatToken oauth2Token = await GetWeChatAccessToken(code != null ? code.ToString() : "");
  31. oauth2Token.id = oauth2Token.access_token;
  32. // oauth2Token.PartitionKey = "WeChatOauth2Token";
  33. // oauth2Token = await SaveOrUpdate<WeChatToken>(oauth2Token);
  34. }
  35. return null;
  36. }
  37. /// <summary>
  38. /// 获取微信AccessToken
  39. /// </summary>
  40. /// <param name="Code"></param>
  41. /// <returns></returns>
  42. private async Task<WeChatToken> GetWeChatAccessTokenClient()
  43. {
  44. string requestUrl = BaseConfigModel.Configuration["WeChat:WeChatAccessTokenUrlClient"] + "appid={{APPID}}&secret={{SECRET}}&code={{CODE}}&grant_type=client_credential";
  45. requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["WeChat:WeChatAppID"]);
  46. requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["WeChat:WeChatAppSecret"]);
  47. string info = await HttpHelper.HttpGetAsync(requestUrl);
  48. return info.FromApiJson<WeChatToken>();
  49. }
  50. /// <summary>
  51. /// 获取微信AccessToken
  52. /// </summary>
  53. /// <param name="Code"></param>
  54. /// <returns></returns>
  55. private async Task<WeChatToken> GetWeChatAccessToken(string Code)
  56. {
  57. if (string.IsNullOrEmpty(Code))
  58. {
  59. return null;
  60. }
  61. string requestUrl = BaseConfigModel.Configuration["WeChat:WeChatAccessTokenUrlCode"] + "appid={{APPID}}&secret={{SECRET}}&code={{CODE}}&grant_type=authorization_code";
  62. requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["WeChat:WeChatAppID"]);
  63. requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["WeChat:WeChatAppSecret"]);
  64. requestUrl = requestUrl.Replace("{{CODE}}", Code);
  65. string info = await HttpHelper.HttpGetAsync(requestUrl);
  66. return info.FromApiJson<WeChatToken>();
  67. }
  68. /// <summary>
  69. /// 获取微信登录跳转链接
  70. /// </summary>
  71. /// <param name="time">13位时间戳</param>
  72. /// <returns></returns>
  73. public Dictionary<string, object> GetWechatConfig(string Time)
  74. {
  75. Dictionary<string, object> config = new Dictionary<string, object>();
  76. config.Add("WeChatAuthorizeUrlCode", BaseConfigModel.Configuration["WeChat:WeChatAuthorizeUrlCode"] + "?appid=" + BaseConfigModel.Configuration["WeChat:WeChatAppID"] + "&redirect_uri={{redirect_uri}}&response_type=code&scope=snsapi_userinfo&state=" + Time + "#wechat_redirect");
  77. return config;
  78. }
  79. public async Task<MiniAPPLoginInfo> VerifyMiniAPP(Dictionary<string, object> dict)
  80. {
  81. MiniAPPLoginInfo loginInfo = null;
  82. if (dict.TryGetValue("js_code", out object js_code))
  83. {
  84. if (string.IsNullOrEmpty(js_code != null ? js_code.ToString() : ""))
  85. {
  86. throw new Exception("Validation failure , js_code is null!");
  87. }
  88. string requestUrl = BaseConfigModel.Configuration["WeChat:MiniAPPAuthUrl"];
  89. requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["WeChat:MiniAPPID"]);
  90. requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["WeChat:MiniAPPSECRET"]);
  91. requestUrl = requestUrl.Replace("{{JSCODE}}", js_code.ToString());
  92. string info = await HttpHelper.HttpGetAsync(requestUrl);
  93. loginInfo = info.FromApiJson<MiniAPPLoginInfo>();
  94. if (loginInfo != null)
  95. {
  96. if (loginInfo.errcode != 0)
  97. {
  98. throw new Exception(loginInfo.errmsg);
  99. }
  100. }
  101. else
  102. {
  103. throw new Exception("Validation failure , loginInfo is null !");
  104. }
  105. }
  106. else
  107. {
  108. throw new Exception("js_code is null !");
  109. }
  110. return loginInfo;
  111. }
  112. /// <summary>
  113. /// 获取微信AccessToken
  114. /// </summary>
  115. /// <param name="Code"></param>
  116. /// <returns></returns>
  117. public async Task<MiniAPPToken> GetMiniAPPAccessToken()
  118. {
  119. string requestUrl = BaseConfigModel.Configuration["WeChat:MiniAPPAccessTokenUrl"];
  120. requestUrl = requestUrl.Replace("{{APPID}}", BaseConfigModel.Configuration["WeChat:MiniAPPID"]);
  121. requestUrl = requestUrl.Replace("{{SECRET}}", BaseConfigModel.Configuration["WeChat:MiniAPPSECRET"]);
  122. string info = await HttpHelper.HttpGetAsync(requestUrl);
  123. MiniAPPToken miniAPPToken = info.FromApiJson<MiniAPPToken>();
  124. if (miniAPPToken != null)
  125. {
  126. if (miniAPPToken.errcode != 0)
  127. {
  128. throw new Exception(miniAPPToken.errmsg);
  129. }
  130. }
  131. else
  132. {
  133. throw new Exception("Validation failure,miniAPPToken is null!");
  134. }
  135. return miniAPPToken;
  136. }
  137. /// <summary>
  138. /// 获取用户登录信息
  139. /// </summary>
  140. /// <param name="unionid"></param>
  141. /// <param name="access_token"></param>
  142. /// <returns></returns>
  143. public WeChatUser GetWeChatUserInfo(string session_key, Dictionary<string, object> dict)
  144. {
  145. string enData = "";
  146. if (dict.TryGetValue("encryptedData", out object encryptedData) && dict.TryGetValue("iv", out object iv))
  147. {
  148. if (encryptedData != null && iv != null)
  149. {
  150. /**
  151. *{"openId":"oLaYK45lBS8HWSAXJisDdIlEWj3A",
  152. * "nickName":"菁華浮梦、℡",
  153. * "gender":1,
  154. * "language":"zh_CN",
  155. * "city":"Chengdu",
  156. * "province":"Sichuan",
  157. * "country":"China",
  158. * "avatarUrl":"https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83er98z4MsFd1xKML71TwQuR1Bxnt7ib3SGrNsKiaBCLYbLeS7KAT8h0ia8byiaVzurvEpVmmQpSzBQs5Nw/132",
  159. * "unionId":"oqADO5qdTR6PItxhmDEPCsWU9PqI",
  160. * "watermark":{"timestamp":1562224447,"appid":"wxf4905703824211aa"}}
  161. **/
  162. enData = WeChatCryptHelper.AESDecrypt(encryptedData.ToString(), session_key, iv.ToString());
  163. }
  164. }
  165. //string requestUrl = BaseConfigModel.Configuration["WeChat:UnionidUserinfo"];
  166. //requestUrl = requestUrl.Replace("{{openid}}", unionid);
  167. //WeChatToken weChatToken = await GetWeChatAccessTokenClient();
  168. //requestUrl = requestUrl.Replace("{{access_token}}", weChatToken.access_token);
  169. //string info = await HttpHelper.HttpGetAsync(requestUrl);
  170. MiniAPPUserInfo miniAPPUser = enData.FromApiJson<MiniAPPUserInfo>();
  171. if (miniAPPUser != null)
  172. {
  173. Expression<Func<WeChatUser, bool>> linq = null;
  174. linq = l => l.unionId == miniAPPUser.unionId;
  175. var weChatUsers = weChatUserService.GetList(linq);
  176. // await SaveOrUpdate<WeChatUser>(weChatUser);
  177. if (weChatUsers.IsNotEmpty())
  178. {
  179. var weChatUser = weChatUsers[0];
  180. weChatUser.nickName = miniAPPUser.nickName;
  181. weChatUser.gender = miniAPPUser.gender;
  182. weChatUser.avatarUrl = miniAPPUser.avatarUrl;
  183. weChatUser.country = miniAPPUser.country;
  184. weChatUser.city = miniAPPUser.city;
  185. weChatUser.province = miniAPPUser.province;
  186. weChatUser.openId = miniAPPUser.openId;
  187. weChatUser.unionId = miniAPPUser.unionId;
  188. weChatUserService.Update(weChatUser);
  189. return weChatUser;
  190. }
  191. else {
  192. var weChatUser = new WeChatUser();
  193. weChatUser.id = Guid.NewGuid().ToString();
  194. weChatUser.nickName = miniAPPUser.nickName;
  195. weChatUser.gender = miniAPPUser.gender;
  196. weChatUser.avatarUrl = miniAPPUser.avatarUrl;
  197. weChatUser.country = miniAPPUser.country;
  198. weChatUser.city = miniAPPUser.city;
  199. weChatUser.province = miniAPPUser.province;
  200. weChatUser.openId = miniAPPUser.openId;
  201. weChatUser.unionId = miniAPPUser.unionId;
  202. weChatUser.registerTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
  203. weChatUserService.Insert(weChatUser);
  204. return weChatUser;
  205. }
  206. }
  207. else
  208. {
  209. throw new Exception("Validation failure,miniAPPToken is null!");
  210. }
  211. }
  212. public async Task<JwtResponse> MiniAPPLogin(Dictionary<string, object> dict)
  213. {
  214. MiniAPPLoginInfo loginInfo = await VerifyMiniAPP(dict);
  215. WeChatUser weChatUser = GetWeChatUserInfo(loginInfo.session_key, dict);
  216. JwtResponse jwt = CreateJwtToken(weChatUser, loginInfo.session_key);
  217. LoginInfo login = new LoginInfo();
  218. login.id = Guid.NewGuid().ToString();
  219. // login.PartitionKey = weChatUser.PartitionKey;
  220. login.TeamModelId = weChatUser.unionId;
  221. login.Token = jwt.Access_token;
  222. login.Scope = jwt.Scope;
  223. return jwt;
  224. }
  225. public JwtResponse CreateJwtToken(WeChatUser user, string sessionKey)
  226. {
  227. ClaimModel model = new ClaimModel
  228. {
  229. Scope = "MiniAPP"
  230. };
  231. if (user != null)
  232. {
  233. model.Claims.Add(new Claim(JwtClaimTypes.SessionId, sessionKey));
  234. model.Claims.Add(new Claim(JwtClaimTypes.Name, user.nickName));
  235. model.Claims.Add(new Claim(JwtClaimTypes.Id, user.unionId));
  236. model.Claims.AddRange("learner".Split(',').Select(s => new Claim(JwtClaimTypes.Role, s)));
  237. model.Roles.Add("learner");
  238. JwtResponse jwtResponse = JwtHelper.IssueJWT(model);
  239. return jwtResponse;
  240. }
  241. else
  242. {
  243. throw new Exception("Validation failure,user is null !");
  244. }
  245. }
  246. }
  247. }