钉钉微应用接入钉钉免登陆配置记录。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 + "&timestamp=" + 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实例上来,说的不清楚的大家可以留言,我一定会回复的。

 

posted @ 2019-03-09 12:57  一小时小超人  阅读(1906)  评论(10编辑  收藏  举报