开发者社区> 问答> 正文

【创联云】钉钉免登demo

一、工具和环境:eclipse+springBoot+Maven+jquery+51手机模拟器
二、阅读官方开发文档并熟记免登流程和步骤



三、按步骤实现:
1、在企业管理后台:https://oa.dingtalk.com/上注册企业完成之后,在企业应用-工作台设置页面里面,可以获取到企业的corpId和CorpSecret。


2、 通过调用获取access_token的接口获取企业的access_token。
// accessToken放到文件中缓存2小时
    public static final long cacheTime = 1000 * 60 * 60 * 2;
    
    /**
     * 2、通过调用获取access_token的接口获取企业的access_token。
     * @return
     * @throws OApiException
     */
    public static String getAccessToken() throws OApiException {
        long curTime = System.currentTimeMillis();
        JSONObject accessTokenValue = (JSONObject) FileUtils.getValue("accesstoken", Env.CORP_ID); //从accesstoken.properties文件中取accesstoken
        String accToken = "";
        String jsTicket = "";
        JSONObject jsontemp = new JSONObject();
        //首次获取accesstoken或者缓存时间超过2小时后重新获取
        if (accessTokenValue == null || curTime - accessTokenValue.getLong("begin_time") >= cacheTime) {
            try
            {
                ServiceFactory serviceFactory = ServiceFactory.getInstance();
                CorpConnectionService corpConnectionService = serviceFactory.getOpenService(CorpConnectionService.class);
                accToken = corpConnectionService.getCorpToken(Env.CORP_ID, Env.CORP_SECRET);
                JSONObject jsonAccess = new JSONObject();
                jsontemp.clear();
                jsontemp.put("access_token", accToken);
                jsontemp.put("begin_time", curTime);
                jsonAccess.put(Env.CORP_ID, jsontemp);
                FileUtils.write2File(jsonAccess, "accesstoken");
                
                if(accToken.length() > 0){
                    JsapiService jsapiService = serviceFactory.getOpenService(JsapiService.class);
                    JsapiTicket JsapiTicket = jsapiService.getJsapiTicket(accToken, "jsapi");
                    jsTicket = JsapiTicket.getTicket();
                    JSONObject jsonTicket = new JSONObject();
                    jsontemp.clear();
                    jsontemp.put("ticket", jsTicket);
                    jsontemp.put("begin_time", curTime);
                    jsonTicket.put(Env.CORP_ID, jsontemp);
                    FileUtils.write2File(jsonTicket, "jsticket");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else {
            return accessTokenValue.getString("access_token");
        }
        return accToken;
    }

3、 通过调用获取jsticket的接口获取企业的jsticket。
/**
     * 3、通过调用获取jsticket的接口获取企业的jsticket。
     * @param accessToken
     * @return
     * @throws OApiException
     */
    public static String getJsapiTicket(String accessToken) throws OApiException {
        JSONObject jsTicketValue = (JSONObject) FileUtils.getValue("jsticket", Env.CORP_ID);
        long curTime = System.currentTimeMillis();
        String jsTicket = "";

         if (jsTicketValue == null || curTime -
         jsTicketValue.getLong("begin_time") >= cacheTime) {
            ServiceFactory serviceFactory;
            try {
                serviceFactory = ServiceFactory.getInstance();
                JsapiService jsapiService = serviceFactory.getOpenService(JsapiService.class);

                JsapiTicket JsapiTicket = jsapiService.getJsapiTicket(accessToken, "jsapi");
                jsTicket = JsapiTicket.getTicket();

                JSONObject jsonTicket = new JSONObject();
                JSONObject jsontemp = new JSONObject();
                jsontemp.clear();
                jsontemp.put("ticket", jsTicket);
                jsontemp.put("begin_time", curTime);
                jsonTicket.put(Env.CORP_ID, jsontemp);
                FileUtils.write2File(jsonTicket, "jsticket");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return jsTicket;
         } else {
             return jsTicketValue.getString("ticket");
         }
    }

4、 在后端通过sign(ticket, nonceStr, timeStamp, url)计算前端校验需要使用的签名信息。
/**
     * 4、在后端通过sign(ticket, nonceStr, timeStamp, url)计算前端校验需要使用的签名信息。
     * @param url
     * @return
     * @throws OApiException
     */
    public static Map<String,Object> getConfig(String url) throws OApiException {
        String accessToken = getAccessToken();
        String JsTicket = getJsapiTicket(accessToken);
        
        String nonceStr = Utils.getRandomStr(16); //随机数生成nonceStr
        long timeStamp = System.currentTimeMillis();
        try {
                String signature = getJsApiSingnature(url, nonceStr, timeStamp, JsTicket);
                Map<String, Object> JsApiConfig = new HashMap<String,Object>();
                JsApiConfig.put("signature", signature);
                JsApiConfig.put("timeStamp", timeStamp);
                JsApiConfig.put("corpId", Env.CORP_ID);
                JsApiConfig.put("agentId", Env.AGENT_ID);
                JsApiConfig.put("nonceStr", nonceStr);
                
                return JsApiConfig;
            } catch (Exception e) {
                e.printStackTrace();
            }
        return null;
    }
    
    public static String getJsApiSingnature(String url,String nonceStr,long timeStamp,String jsTicket) throws DingTalkEncryptException{
        String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "×tamp=" + String.valueOf(timeStamp) + "&url=" + url;
          System.out.println(plainTex);
          String signature = "";
          try{
              MessageDigest crypt = MessageDigest.getInstance("SHA-1");
              crypt.reset();
              crypt.update(plainTex.getBytes("UTF-8"));
              signature = byteToHex(crypt.digest());
              return signature;
          }catch (Exception e){
              throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
          }
      }
    
      private static String byteToHex(final byte[] hash) {
          Formatter formatter = new Formatter();
          for (byte b : hash){
              formatter.format("%02x", b);
          }
          String result = formatter.toString();
          formatter.close();
          return result;
      }

5、 将:‘url’,‘nonceStr’,‘agentId’,‘timeStamp’,‘corpId’,‘signature’传递到前端页面,在前端页面使用jsapi提供的dd.config(PC客户端使用DingTalkPC.config)接口进行签名校验。
@Controller
@RequestMapping("/")
public class MainController {

    @Autowired
    private ServiceHelper serviceHelper;
    
    @RequestMapping("/demo")
    public String index(){
        return "index";
    }
    
    @CrossOrigin
    @RequestMapping("/get_js_config")
    @ResponseBody
    public Map<String,Object> getJsConfig(@RequestParam(value="url",required = false) String url) throws OApiException{
        return AuthHelper.getConfig(url);
    }
    
    @CrossOrigin
    @RequestMapping("/get-user-info")
    @ResponseBody
    public JSONObject getUserInfo(String code) throws OApiException{
        return JSONObject.parseObject(serviceHelper.getUserInfo(AuthHelper.getAccessToken(),code));
    }
    
    @CrossOrigin
    @RequestMapping("/api_get")
    @ResponseBody
    public JSONObject getUserInfoById(String code) throws OApiException{
        return JSONObject.parseObject(serviceHelper.getUserInfoById(AuthHelper.getAccessToken(),JSONObject.parseObject(serviceHelper.getUserInfo(AuthHelper.getAccessToken(),code)).getString("userid")));
    }
}


6、在页面引入jsapi:https://g.alicdn.com/ilw/ding/0.9.2/scripts/dingtalk.js
7、使用钉钉js-api提供的获取免登授权码接口获取CODE
8、通过CODE换取身份
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>创联云钉钉二次开发</title>
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js" charset="utf-8"></script>
<script src="https://g.alicdn.com/ilw/ding/0.9.2/scripts/dingtalk.js" charset="utf-8"></script>
            
</head>
<script type="text/javascript">
    Window.authcode = "";
    $(document).ready(function(){
        var url = window.location.href;
        var corpId="";
        var signature = "";
        var nonceStr = "";
        var timeStamp = "";
        var agentId= "";
        
        $.post(
            'get_js_config',
            {
                "url":url
            },
            function(result){
                corpId= result.corpId;
                signature = result.signature;
                nonceStr = result.nonceStr;
                timeStamp = result.timeStamp;
                agentId= result.agentId;
                
                dd.config({
                    agentId : agentId,  
                    corpId : corpId,  
                    timeStamp : timeStamp,  
                    nonceStr : nonceStr,  
                    signature :signature,  
                    jsApiList : [
                        'runtime.info',            
                        'biz.contact.choose',
                        'device.notification.confirm',
                        'device.notification.alert',  
                        'device.notification.prompt',
                        'biz.ding.post',
                        'biz.util.openLink' ]  
                     });
                
                dd.ready(function() {
                    dd.runtime.info({  
                        onSuccess : function(info) {  
                        console.log('runtime info: ' + JSON.stringify(info));  
                        },  
                        onFail : function(err) {  
                            console.log('fail: ' + JSON.stringify(err));
                        }  
                    });
                        
                    dd.runtime.permission.requestAuthCode({  
                        corpId : corpId,  
                        onSuccess : function(info) {
                             Window.authcode = info.code;
                             $.get(
                                'api_get',
                                {
                                    "code":info.code
                                },
                                function(result){
                                    $("#agent").empty();
                                    $("#agent").append(result.name);
                                }
                            );
                              
                        },  
                        onFail : function(err) {
                            console.log('requestAuthCode: ' + JSON.stringify(err));
                        }  
                    });
                });
                dd.error(function(err) {  
                    alert('dd error: ' + JSON.stringify(err));  
                });
            }
        )
    });
</script>
<style type="text/css">
.btn{
    height:40pxp;
    width:200px;
    font-size:24px;
    font-family:"Arial black";
}
.content{
    font-size:48px;
    font-family:"Arial black";
}
.head{
    align-content:center;
    font-size:18px;
}
</style>
<body>
<div class="head">
     免登demo
</div>
<div>
    <div style="...">
        <!-- <button class="btn" onclick="getAgentInfo()">获取用户信息</button>  -->
        欢迎登录! <div id ="agent" class="contert"></div>
    </div>
</div>
</body>
</html>

演示图:

展开
收起
steven_1205 2017-05-27 01:01:04 4971 0
0 条回答
写回答
取消 提交回答
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
钉钉小程序——为工作方式插上翅膀 立即下载
钉钉客户端自动化的应用 立即下载
使命必达 —— 钉钉企业级 消息服务的机遇与挑战 立即下载