釘釘免登錄
阿新 • • 發佈:2018-12-08
調用 The ref json.js ext public 感謝 eee empty
流程
首先需要理解一下釘釘的免登流程,借用官方文檔的圖片:
免登錄步奏
- 已知Corpld和CropSecret,獲取accessToken,即訪問令牌。
- 通過accessToken,獲取JsApiTicket,即JsApi的訪問許可(門票)。
- 按照規則在後臺由JsApiTicket、NonceStr、Timestamp、前端頁面Url生成字符串,計算SHA1消息摘要,即簽名Signature。
- 把AgentId、CorpId、Timestamp、NonceStr、Signature等參數傳遞到前臺,在前臺調用api,得到authCode,即授權碼。
- 根據授權碼,在前臺或後臺調用api,獲得userId,進而再根據userId,調用api獲取用戶詳細信息
主要代碼
DingServerController
using Common; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using WebApIs.BLL; using WebApIs.Models; namespace WebApIs.Controllers {/// <summary>View Code/// /// </summary> public class DingServerController : ApiController { /// <summary> /// /// </summary> /// <returns></returns> public ResultJson GetLoginSign() { string corpId = "dinga85d93", corpSecret = "D5r1G6cejOlZmEaB8PNlI9J5D"; string nonceStr = new Random().Next(1000, 10000).ToString(); //"helloDD";//todo:隨機 string NonceStr = nonceStr; string AccessToken = GetAccessToken(corpId, corpSecret); string ticket = GetJsApiTicket(AccessToken); TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); long timeStamp = Convert.ToInt64(ts.TotalSeconds); //?後端缺獲取簽名摘要 string url = "http://10.10.10.10:8084/Index.html";//訪問的頁面 Request.Url.ToString(); string signature = ""; int sta = DDev.GetSign(ticket, nonceStr, timeStamp, url, ref signature); return new ResultJson { agentId = "207623633", corpId = corpId, timeStamp = timeStamp, nonceStr = NonceStr, signature = signature }; } /// <summary> /// / /// </summary> /// <param name="code"></param> /// <returns></returns> // [HttpPost] public ResultJson GetCurrentUser(string code) { HROCPeopleBll ppbll = new HROCPeopleBll(); string corpId = "dinga85d9", corpSecret = "D5r1G6cejOlZmEaB8PNlI9J5"; string access_token = GetAccessToken(corpId, corpSecret); string tagUrl = "https://oapi.dingtalk.com/user/getuserinfo?access_token=" + access_token + "&code=" + code; string result = GetContents(tagUrl); var userModel = JsonConvert.DeserializeObject<UserInfo>(result); string ddid = userModel.userid; HROCPeople pp = new HROCPeople(); pp = ppbll.GetPeopleModel(ddid); userModel.BpmLoginName = pp.LoginName; userModel.BpmUserID = pp.ID; userModel.BpmUserName = pp.Name; return new ResultJson { DetailData = userModel }; // var dtmodel= JsonConvert.DeserializeObject<HROCPeople>(dt); //return new ResultJson { DetailData= pp.Name,data=pp.LoginName }; } /// <summary> /// /// </summary> /// <param name="DDID"></param> /// <returns></returns> public ResultJson GetCurrentUsers(string DDID) { HROCPeopleBll ppbll = new HROCPeopleBll(); HROCPeople hrp = ppbll.GetPeopleModel(DDID); return new ResultJson { DetailData = hrp }; } /// <summary> /// /// </summary> /// <param name="DDID"></param> /// <returns></returns> public string GetName(string DDID) { //return string.Format("姓名:{0}", Name); HROCPeopleBll ppbll = new HROCPeopleBll(); HROCPeople hrp = ppbll.GetPeopleModel(DDID); return string.Format("姓名:{0},登錄名:{1},ID:{2} ", hrp.Name, hrp.LoginName, hrp.ID); //return new ResultJson { data = hrp.Name, signature= hrp.LoginName }; } //POST api/DingServer/GetCurrentUser? code = { code } /// <summary> /// /// </summary> /// <param name="corpId"></param> /// <param name="corpSecret"></param> /// <returns></returns> public string GetAccessToken(string corpId, string corpSecret) { string url = string.Format("https://oapi.dingtalk.com/gettoken?corpid={0}&corpsecret={1}", corpId, corpSecret); try { string response = GetContents(url); AccessTokenModel oat = Newtonsoft.Json.JsonConvert.DeserializeObject<AccessTokenModel>(response); if (oat != null) { if (oat.errcode == 0) { return oat.access_token; } } } catch (Exception ex) { throw; } return string.Empty; } public string GetJsApiTicket(string accessToken) { string url = string.Format("https://oapi.dingtalk.com/get_jsapi_ticket?access_token={0}", accessToken); try { string response = GetContents(url); JsApiTicketModel model = Newtonsoft.Json.JsonConvert.DeserializeObject<JsApiTicketModel>(response); if (model != null) { if (model.errcode == 0) { return model.ticket; } } } catch (Exception ex) { throw ex; } return string.Empty; } public static string GetContents(string url) { WebRequest request = HttpWebRequest.Create(url); WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); StreamReader reader = new StreamReader(stream); string content = reader.ReadToEnd(); return content; } } public class AccessTokenModel { public string access_token { get; set; } public int errcode { get; set; } public string errmsg { get; set; } } public class JsApiTicketModel { public string ticket { get; set; } public int errcode { get; set; } public string errmsg { get; set; } } public class UserIdModel { public string userid { get; set; } public int errcode { get; set; } public string errmsg { get; set; } } public class UserDetailInfo { public string userid { get; set; } public int errcode { get; set; } public string username { get; set; } } }
HROCPeople
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebApIs.Models { public class HROCPeople { public string ID { get; set; } public int IntID { get; set; } public string JobID { get; set; } public string CreateTime { get; set; } public string Name { get; set; } public string LoginName { get; set; } public string CompanyID { get; set; } public string DepartmentID { get; set; } //釘釘號 格式:{"DING":"211202322424329696"} public string other1 { get; set; } } }View Code
釘釘幫助類
using System; using System.Text; using System.Security.Cryptography; using System.Collections; namespace Common { public static class DDev { public static int GenSigurate(string jsapi_ticket, string noncestr, string sTimeStamp, string url, ref string signature) { string assemble = string.Format("jsapi_ticket={0}&noncestr={1}×tamp={2}&url={3}", jsapi_ticket, noncestr, sTimeStamp, url); SHA1 sha; ASCIIEncoding enc; string hash = ""; try { sha = new SHA1CryptoServiceProvider(); enc = new ASCIIEncoding(); byte[] dataToHash = enc.GetBytes(assemble); byte[] dataHashed = sha.ComputeHash(dataToHash); hash = BitConverter.ToString(dataHashed).Replace("-", ""); hash = hash.ToLower(); } catch (Exception) { return 2; } signature = hash; return 0; } public static int GetSign(string ticket, string nonceStr, long timeStamp, string url, ref string signature) { String plain = string.Format("jsapi_ticket={0}&noncestr={1}×tamp={2}&url={3}", ticket, nonceStr, timeStamp, url); try { byte[] bytes = Encoding.UTF8.GetBytes(plain); byte[] digest = SHA1.Create().ComputeHash(bytes); string digestBytesString = BitConverter.ToString(digest).Replace("-", ""); signature = digestBytesString.ToLower(); return 1; } catch (Exception e) { throw e; } } /// <summary> /// 獲取時間戳timestamp(當前時間戳,具體值為當前時間到1970年1月1號的秒數) /// </summary> /// <returns></returns> public static string GetTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /// <summary> /// 字典排序 /// </summary> public class DictionarySort : System.Collections.IComparer { public int Compare(object oLeft, object oRight) { string sLeft = oLeft as string; string sRight = oRight as string; int iLeftLength = sLeft.Length; int iRightLength = sRight.Length; int index = 0; while (index < iLeftLength && index < iRightLength) { if (sLeft[index] < sRight[index]) return -1; else if (sLeft[index] > sRight[index]) return 1; else index++; } return iLeftLength - iRightLength; } } } }View Code
前端代碼
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>釘釘服務接口調試</title> <!--<script type="text/javascript" src="script/jquery.min.js"></script> <script type="text/javascript" src="script/bootstrap.min.js"></script>--> <script src="//cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.5.1/dingtalk.js"></script> <link type="text/css" rel="stylesheet" href="content/bootstrap.css" media="screen" /> <style> body { margin: 20px 20px; } </style> </head> <body> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">用戶接口</h3> </div> <input id="notice" type="text" /> <div class="panel-body"> <div class="method-margin col-md-12"> <div style="margin-bottom:5px;"> <button type="button" class="btn btn-default" data-loading-text="正在請求..." id="getUserDetail">獲取用戶詳情</button> </div> <div class="method-output-padding"> <div class="logs-margin alert alert-danger alert-dismissible" role="alert" name="showErrorAlert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <span name="errorText"></span> </div> <div class="logs-margin alert alert-success alert-dismissible" role="alert" name="showInfoAlert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">×</span> </button> <span name="successText"></span> </div> </div> </div> </div> </div> <script type="text/javascript"> function login1(id) { $.ajax({ url: ‘http://10.10.10.10:8081/api/DingServer/GetName‘, type: ‘get‘, // dataType: ‘JSON‘, data: { "DDID": id }, success: function (data) { // alert(JSON.stringify(data)) alert(data) //var DDID = data.DetailData.userid; //alert(DDID) //login1(data.DetailData.userid) }, error: function (data) { // alert(JSON.stringify(data)) } }) } //function login1(id) { // $.ajax({ // url: ‘http://10.10.10.10:8081/api/DingServer/GetCurrentUsers‘, // type: ‘get‘, // // dataType: ‘JSON‘, // data: { DDID: id }, // success: function (data) { // alert(data) // //var DDID = data.DetailData.userid; // //alert(DDID) // //login1(data.DetailData.userid) // }, // error: function (data) { // alert(JSON.stringify(data)) // } // }) //} function login(code) { $.ajax({ url: ‘http://10.10.10.10:8081/api/DingServer/GetCurrentUser‘, type: ‘GET‘, // dataType: ‘JSON‘, data: {code:code }, success: function (data, status, xhr) { //alert(JSON.stringify(data)) alert(data.DetailData.BpmUserID + "-" + data.DetailData.BpmUserName + "-" + data.DetailData.BpmLoginName) }, error: function (data) { alert(JSON.stringify(data)) } }) } //獲取簽名摘要?? $(document).ready(function () { $.ajax({ url: "http://10.10.10.10:8081/api/DingServer/GetLoginSign", type: ‘GET‘, success: function (data, status, xhr) { if (data.code != 0) { } else { var str = JSON.stringify(data); // alert(str); dd.config({ agentId: data.agentId, corpId: data.corpId, timeStamp: data.timeStamp, nonceStr: data.nonceStr, signature: data.signature, jsApiList: [‘runtime.info‘, ‘biz.contact.choose‘, ‘device.notification.confirm‘, ‘device.notification.alert‘, ‘device.notification.prompt‘, ‘biz.ding.post‘, ‘biz.util.openLink‘] }); dd.error(function (err) { alert(‘dd error: ‘ + JSON.stringify(err)) }) dd.ready(function () { dd.runtime.permission.requestAuthCode({ corpId: data.corpId, onSuccess: function (result) { alert(JSON.stringify(result)) login(result.code) } }) }) } }, error: function (data) { console.log(‘err:‘, data) } }) }) </script> </body> </html>View Code
釘釘管理員配置應用
釘釘免登就是這樣,只要弄懂了就會覺得其實不難。感謝閱讀。
釘釘免登錄