LoginController.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. using Azure.Cosmos;
  2. using DingTalk.Api;
  3. using DingTalk.Api.Request;
  4. using DingTalk.Api.Response;
  5. using Microsoft.AspNetCore.Http;
  6. using Microsoft.AspNetCore.Mvc;
  7. using Microsoft.Extensions.Configuration;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK.Models;
  15. using HTEXLib.COMM.Helpers;
  16. using TEAMModelOS.Models;
  17. using static TEAMModelOS.SDK.Models.Teacher;
  18. using Microsoft.Extensions.Options;
  19. using TEAMModelOS.SDK.Extension;
  20. using TEAMModelOS.SDK.Models.Service;
  21. using static TEAMModelOS.Controllers.Third.ScController;
  22. namespace TEAMModeBI.Controllers
  23. {
  24. [ProducesResponseType(StatusCodes.Status200OK)]
  25. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  26. [Route("common/login")]
  27. [ApiController]
  28. public class LoginController : ControllerBase
  29. {
  30. private readonly IConfiguration _configuration;
  31. //数据容器
  32. private readonly AzureCosmosFactory _azureCosmos;
  33. //文件容器
  34. private readonly AzureStorageFactory _azureStorage;
  35. //钉钉提示信息
  36. private readonly DingDing _dingDing;
  37. private readonly Option _option;
  38. //隐世登录
  39. private readonly CoreAPIHttpService _accountHttpService;
  40. string type = "ddteammodel";
  41. public LoginController(IConfiguration configuration, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService)
  42. {
  43. _configuration = configuration;
  44. _azureCosmos = azureCosmos;
  45. _azureStorage = azureStorage;
  46. _dingDing = dingDing;
  47. _option = option?.Value;
  48. _accountHttpService = coreAPIHttpService;
  49. }
  50. /// <summary>
  51. /// 钉钉扫描登录
  52. /// </summary>
  53. /// <param name="loginTmpCode"></param>
  54. /// <returns>Json结果</returns>
  55. [ProducesDefaultResponseType]
  56. [HttpGet("dingding")]
  57. public IActionResult DingDingLogin(string loginTmpCode)
  58. {
  59. string appKey = _configuration["DingDingAuth:appKey"];
  60. string appSecret = _configuration["DingDingAuth:appSecret"];
  61. string getuserinfo_bycode = _configuration["DingDingAuth:getuserinfo_bycode"];
  62. //判断参数是否为空
  63. if (string.IsNullOrEmpty(loginTmpCode))
  64. {
  65. return BadRequest("temp code error");
  66. }
  67. //获取access_token
  68. DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  69. OapiGettokenRequest request = new OapiGettokenRequest();
  70. request.Appkey = appKey;
  71. request.Appsecret = appSecret;
  72. request.SetHttpMethod("Get");
  73. OapiGettokenResponse response = client.Execute(request);
  74. if (response.IsError)
  75. {
  76. return BadRequest();
  77. }
  78. string access_token = response.AccessToken;
  79. //获取临时授权码 获取授权用户的个人信息
  80. DefaultDingTalkClient client1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
  81. OapiSnsGetuserinfoBycodeRequest bycodeRequest = new OapiSnsGetuserinfoBycodeRequest()
  82. {
  83. //通过扫描二维码,跳转到指定的Url后,向Url中追加Code临时授权码
  84. TmpAuthCode = loginTmpCode
  85. };
  86. OapiSnsGetuserinfoBycodeResponse bycodeResponse = client1.Execute(bycodeRequest, appKey, appSecret);
  87. if (bycodeResponse.IsError)
  88. {
  89. return BadRequest();
  90. }
  91. //根据unionid获取userid
  92. string unionid = bycodeResponse.UserInfo.Unionid;
  93. DefaultDingTalkClient clientDingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
  94. OapiUserGetbyunionidRequest byunionidRequest = new OapiUserGetbyunionidRequest()
  95. {
  96. Unionid = unionid
  97. };
  98. OapiUserGetbyunionidResponse byunionidResponse = clientDingTalkClient.Execute(byunionidRequest, access_token);
  99. if (byunionidResponse.IsError)
  100. {
  101. return BadRequest();
  102. }
  103. string userid = byunionidResponse.Result.Userid;
  104. //根据userId获取用户信息
  105. DefaultDingTalkClient clientDingTalkClient2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
  106. OapiV2UserGetRequest getRequest = new OapiV2UserGetRequest()
  107. {
  108. Userid = userid,
  109. Language = "zh_CN"
  110. };
  111. getRequest.SetHttpMethod("Get");
  112. OapiV2UserGetResponse getResponse = clientDingTalkClient2.Execute(getRequest, access_token);
  113. if (getResponse.IsError)
  114. {
  115. return BadRequest();
  116. }
  117. return Ok(getResponse.Body);
  118. }
  119. /// <summary>
  120. /// 钉钉扫码登录
  121. /// </summary>
  122. /// <param name="requert"></param>
  123. /// <returns>Json结果</returns>
  124. [ProducesDefaultResponseType]
  125. [HttpGet("DingLogin")]
  126. public async Task<IActionResult> DingLogin(string LoginTempCode)
  127. {
  128. string temp_mess = null;
  129. //state 是前端传入的,钉钉并不会修改,比如有多种登录方式的时候,一个登录方法判断登录方式可以进行不同的处理。
  130. try
  131. {
  132. string str_appKey = _configuration["DingDingAuth:appKey"];
  133. string str_appSecret = _configuration["DingDingAuth:appSecret"];
  134. if (string.IsNullOrWhiteSpace(str_appKey) || string.IsNullOrWhiteSpace(str_appSecret))
  135. {
  136. return BadRequest("请先配置钉钉扫码登录信息!");
  137. }
  138. //自己传的code
  139. //if (!jsonElement.TryGetProperty("tempCode", out JsonElement LoginTempCode)) return BadRequest();
  140. string loginTempCode = LoginTempCode.ToString();
  141. //判断参数是否为空
  142. if (string.IsNullOrEmpty(LoginTempCode.ToString()))
  143. {
  144. return BadRequest("temp code error");
  145. }
  146. //获取企业内部应用的accessToken
  147. DefaultDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  148. OapiGettokenRequest request = new OapiGettokenRequest();
  149. request.Appkey = str_appKey;
  150. request.Appsecret = str_appSecret;
  151. request.SetHttpMethod("GET");
  152. OapiGettokenResponse tokenResponse = Iclient.Execute(request);
  153. if (tokenResponse.IsError)
  154. {
  155. return Ok(new { ddbinds = $"status=-1"});
  156. }
  157. string access_token = tokenResponse.AccessToken;
  158. //获取临时授权码 获取授权用户的个人信息
  159. DefaultDingTalkClient clientinfo = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
  160. OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest() { TmpAuthCode = loginTempCode }; //通过扫描二维码,跳转到指定的Url后,向Url中追加Code临时授权码
  161. OapiSnsGetuserinfoBycodeResponse response = clientinfo.Execute(req, str_appKey, str_appSecret);
  162. if (response.IsError)
  163. {
  164. return BadRequest();
  165. }
  166. string unionid = response.UserInfo.Unionid;
  167. IDingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid"); //userid地址
  168. OapiUserGetbyunionidRequest byunionidRequest = new OapiUserGetbyunionidRequest() { Unionid = unionid };
  169. OapiUserGetbyunionidResponse byunionidResponse = client2.Execute(byunionidRequest, access_token);
  170. if (byunionidResponse.IsError)
  171. {
  172. return BadRequest();
  173. }
  174. // 根据userId获取用户信息
  175. string userid = byunionidResponse.Result.Userid;
  176. IDingTalkClient client3 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
  177. OapiV2UserGetRequest v2GetRequest = new OapiV2UserGetRequest()
  178. {
  179. Userid = userid,
  180. Language = "zh_CN"
  181. };
  182. v2GetRequest.SetHttpMethod("POST");
  183. OapiV2UserGetResponse v2GetResponse = client3.Execute(v2GetRequest, access_token);
  184. if (v2GetResponse.IsError)
  185. {
  186. return BadRequest();
  187. }
  188. var DDbind = v2GetResponse.Result;
  189. //return Ok(new { v2GetResponse.Result ,v2GetResponse.Body});
  190. DingDingBind dingDingBind = new DingDingBind
  191. {
  192. type = type,
  193. unionid = DDbind.Unionid,
  194. userid = DDbind.Userid,
  195. name = DDbind.Name,
  196. mobile = DDbind.Mobile,
  197. title = DDbind.Title,
  198. DeptIdList = DDbind.DeptIdList,
  199. jobNumber = DDbind.JobNumber,
  200. };
  201. Teacher teacher = null;
  202. string sql = $"select distinct value(c) from c join A1 in c.ddbinds where A1.userid='{dingDingBind.userid}' AND A1.unionid ='{dingDingBind.unionid}'";
  203. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  204. {
  205. teacher = item;
  206. break;
  207. }
  208. if (teacher == null)
  209. {
  210. return Ok(new { ddbinds = $"status=0&dingDingBind={dingDingBind.ToJsonString()}" });
  211. }
  212. else
  213. {
  214. var url = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
  215. var clientID = _configuration.GetValue<string>("HaBookAuth:clientID");
  216. var clientSecret = _configuration.GetValue<string>("HaBookAuth:clientSecret");
  217. var logintion = _option.Location;
  218. //隐式登录
  219. (int code, string content) = await _accountHttpService.Implicit(clientID, clientSecret, logintion, $"{url}/oauth2/implicit",
  220. new Dictionary<string, string>()
  221. {
  222. { "grant_type", "implicit" },
  223. { "client_id",clientID},
  224. { "account",teacher.id},
  225. { "nonce",Guid.NewGuid().ToString()}
  226. });
  227. TmdidImplicit implicit_token = new TmdidImplicit();
  228. if (!string.IsNullOrEmpty(content) && code == 200)
  229. {
  230. implicit_token = content.ToObject<TmdidImplicit>();
  231. var ddbind = teacher.ddbinds.Find(x => x.userid.Equals($"{dingDingBind.userid}") && x.unionid.Equals($"{dingDingBind.unionid}"));
  232. if (ddbind != null)
  233. {
  234. return Ok(new { ddbinds = $"status=200$id_token={implicit_token.id_token}&access_token={implicit_token.access_token}&expires_in={implicit_token.expires_in}&token_type={implicit_token.token_type}" });
  235. }
  236. }
  237. return Ok(new { ddbinds= $"status=1&param={dingDingBind.ToJsonString()}&type={type}&bindurl=sc/bind" });
  238. }
  239. }
  240. catch (Exception e)
  241. {
  242. return BadRequest($"{temp_mess }{e.Message}{e.StackTrace} ");
  243. }
  244. }
  245. }
  246. }