钉钉微应用接入钉钉免登陆配置记录。NET实现
在这里记录一下我配置的钉钉接入微应用遇到的坑。搞了我几天天才调通。头皮发麻,现在梳理一下,以免别人也入坑。
1.钉钉接入主要要获取钉钉企业员工的ID,然后去自己的应用的数据库里进行匹配然后实现免登陆的操作。
2.这里面主要有2个重要操作:一个是鉴权,一个是免登。如果只是简单的免登操作,其实不需要鉴权的,鉴权的目的是为了可以调用其他jsapi接口使用钉钉其他接口。
3.如果要鉴权,要放在免登操作的前面。
4.下面是钉钉上文档找来的图片,这张图的已经有点落伍了,图上的CorpSecret已经没有了。获取Token已经变成通过AgentId和AppSecret来获得,具体看下文。
5.下面来说一下从头到位的具体流程
a.首先登陆钉钉创建应用,获取到4个我们要用到的重要的值:corpId,AgentId,AppKey,AppSecret, 这个四个值分别为企业ID,应用ID,应用Key,应用密钥。
b.我们来说下这个四个值的作用:企业ID corpId 是为了获取Code码,Code码是为了获取到用户的基础信息UserId,然后通过UserId,就可以获取到完整的信息。AppKey和AppSecret是为了获取Token值,前面Code 和userId要获取用户的信息必须要和Token一起才能获取用户信息。
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实例上来,说的不清楚的大家可以留言,我一定会回复的。