在这里记录一下我配置的钉钉接入微应用遇到的坑。搞了我几每天才调通。头皮发麻,如今梳理一下,以避免别人也入坑。前端
1.钉钉接入主要要获取钉钉企业员工的ID,而后去本身的应用的数据库里进行匹配而后实现免登录的操做。数据库
2.这里面主要有2个重要操做:一个是鉴权,一个是免登。若是只是简单的免登操做,其实不须要鉴权的,鉴权的目的是为了能够调用其余jsapi接口使用钉钉其余接口。json
3.若是要鉴权,要放在免登操做的前面。api
4.下面是钉钉上文档找来的图片,这张图的已经有点落伍了,图上的CorpSecret已经没有了。获取Token已经变成经过AgentId和AppSecret来得到,具体看下文。app
5.下面来讲一下从头到位的具体流程post
a.首先登录钉钉建立应用,获取到4个咱们要用到的重要的值:corpId,AgentId,AppKey,AppSecret, 这个四个值分别为企业ID,应用ID,应用Key,应用密钥。ui
b.咱们来讲下这个四个值的做用:企业ID corpId 是为了获取Code码,Code码是为了获取到用户的基础信息UserId,而后经过UserId,就能够获取到完整的信息。AppKey和AppSecret是为了获取Token值,前面Code 和userId要获取用户的信息必需要和Token一块儿才能获取用户信息。this
6.如今来看一下具体的获取Token操做编码
public string GetDingToken() { string token = string.Empty; if (string.IsNullOrEmpty(token)) { string url = string.Format("https://oapi.dingtalk.com/gettoken?corpid={0}&corpsecret={1}", _appId, _appSecret); string json = HttpHelper.GetDataGetHtml(url);//HTTP请求的帮助类,这个类跟本文没有关系,就不贴上来了。 Access_Token access_token = JsonHelper.JsonDeserialize<Access_Token>(json); token = access_token.access_token; } return token; }
7.获取经过Code基础信息的操做(获取的信息很是有限只有一个userId有用为了获取整个用户的信息)加密
public Access_UserInfo GetUserInfo(string code) { string url = string.Format("https://oapi.dingtalk.com/user/getuserinfo?access_token={0}&code={1}", GetDingToken(), code); string json = HttpHelper.GetDataGetHtml(url); return JsonHelper.JsonDeserialize<Access_UserInfo>(json); }
8.经过 userId获取钉钉用户信息的操做(关于免登录的操做相关的后台代码就这些了,剩下还有鉴权相关的一些代码后台代码和前台获获取Code的一些前端请求代码)
public DingUser GetUeser(string uid) { string url = string.Format("https://oapi.dingtalk.com/user/get?access_token={0}&userid={1}", GetDingToken(), uid); string json = HttpHelper.GetDataGetHtml(url); return JsonHelper.JsonDeserialize<DingUser>(json); }
9.鉴权的前端配置代码(这里要先引用钉钉JS文件,之前区分手机可客户端后来不区分了)
dd.config({ agentId: '', // 必填,微应用ID corpId: '',//必填,企业ID timeStamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '', // 必填,签名 type:0/1, //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持 jsApiList : [ 'runtime.info', 'biz.contact.choose', 'device.notification.confirm', 'device.notification.alert', 'device.notification.prompt', 'biz.ding.post', 'biz.util.openLink', ] // 必填,须要使用的jsapi列表,注意:不要带dd。 });
这个几个的参数说明上面已经有备注,这些须要从后台返回这些参数。agentId,和CorpId是现成的,timeStamp生成一个就行了,nonceStrye也是随机生成的一个编码,
,主要是signature是须要几个参数拼成一块儿生成的。下面看看鉴权的后台代码(signature须要ticket+noncestr+timestamp+当前url一块儿生成)JSAPI鉴权官方文档
下面是NET实现的代码
private Access_Sdk GetSdk(string url) { string noncestr = GuidTo16String(); string timestamp = DateTime.Now.Ticks.ToString(); Access_Ticket access_Ticket = GetTicket(); string str1 = "jsapi_ticket=" + access_Ticket.ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url + ""; string signature = str1.Sha1(); Access_Sdk sdk = new Access_Sdk(); sdk.Noncestr = noncestr; sdk.Timestamp = timestamp; sdk.Signature = signature; return sdk; }
这段代码主要有2个要说明的地方一个就是生成Ticket,一个就是 Sha1进行编码。
生成Ticket的编码
private Access_Ticket GetTicket() { string url = string.Format("https://oapi.dingtalk.com/get_jsapi_ticket?access_token={0}", GetDingToken()); string json = HttpHelper.GetDataGetHtml(url); return JsonHelper.JsonDeserialize<Access_Ticket>(json); }
sha1加密
public static string Sha1(this string str) { var buffer = Encoding.UTF8.GetBytes(str); var data = SHA1.Create().ComputeHash(buffer); var sb = new StringBuilder(); foreach (var t in data) { sb.Append(t.ToString("X2")); } return sb.ToString().ToLower(); }
后台的主要代码我都贴上了,下面贴下前台的获取Code的代码
dd.ready(function() { dd.runtime.permission.requestAuthCode({ corpId: _config.corpId, // 企业id onSuccess: function (info) { code = info.code // 经过该免登受权码能够获取用户身份 }}); });
到这里就结束了,原本想写的详细点,可是感受还挺可贵,其实这个东西不难,主要是第一次搞的时候,没有清楚的文档,遇到一两个坑很烦人。心态都爆炸了。
后面我尽可能放一份完整的demo实例上来,说的不清楚的你们能够留言,我必定会回复的。