最近做了个钉钉企业内部微应用的项目。记录下自己的心得。
首先根据官方文档明白免登流程

但是,最近更新的开发者平台,已经不在提供corpSecret了,所以获取获取access_token就要获取获取appKey和appSecret,官方文档写的很清楚,获取access_token如下图所示:

封装一个AuthHelper 如下:
/**

  • 1.获取accessToken

  • 2.获取jsapi中的ticket

  • 3.生成jsapiz中的鉴权sign

  • 4.根据传入的临时code获取用户的基本信息,入userinfo

  • 5.(ISV版本)根据userid获取详细用户信息

  • @author lnexin
    */
    public class AuthHelper {

    // 钉钉api相关
    static String TOKEN_URL = “https://oapi.dingtalk.com/gettoken”;
    static String TICKET_URL = “https://oapi.dingtalk.com/get_jsapi_ticket”;
    static String USER_INFO_URL = “https://oapi.dingtalk.com/user/getuserinfo”;
    static String USER_ALL_URL = “https://oapi.dingtalk.com/user/get”;

    // 调整到1小时50分钟
    public static final long cacheTime = 1000 * 60 * 55 * 2;

    private static String ACCESS_TOKEN = null;
    private static String JSAPI_TICKET = null;
    private static long LAST_TIME = 0;

    /**

    • @param appKey

    • @param appSecret

    • @return 与钉钉服务器请求生成的accessToken
      */
      public static String getAccessToken(String appKey, String appSecret) {
      long curTime = System.currentTimeMillis();
      long differ = curTime - LAST_TIME;

      if (ACCESS_TOKEN != null && differ < cacheTime)
      return ACCESS_TOKEN;

      ACCESS_TOKEN = requestAccessToken(appKey, appSecret);
      LAST_TIME = curTime;

      return ACCESS_TOKEN;
      }

    /**

    • @param accessToken

    • @return 一个用于js鉴权的ticket
      */
      public static String getJsapiTicket(String accessToken) {
      long curTime = System.currentTimeMillis();
      long differ = curTime - LAST_TIME;

      if (JSAPI_TICKET != null && differ < cacheTime) {
      return JSAPI_TICKET;
      }
      JSAPI_TICKET = requestJsapiTicket(accessToken);
      return JSAPI_TICKET;
      }

    /**

    • 根据传入的相关参数生成sign
    • @param ticket
    • @param nonceStr
    • @param timeStamp
    • @param url
    • @return
      */
      public static String sign(String ticket, String nonceStr, long timeStamp, String url) {
      StringBuffer plain = new StringBuffer();
      plain.append(“jsapi_ticket=”).append(ticket);
      plain.append("&noncestr=").append(nonceStr);
      plain.append("&timestamp=").append(String.valueOf(timeStamp));
      plain.append("&url=").append(url);
      MessageDigest sha;
      try {
      sha = MessageDigest.getInstance(“SHA-1”);
      sha.reset();
      sha.update(plain.toString().getBytes(“UTF-8”));
      return bytesToHex(sha.digest());
      } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
      }
      return null;
      }

    private static String requestAccessToken(String appKey, String appSecret) {
    StringBuffer url = new StringBuffer(TOKEN_URL);
    url.append("?appkey=").append(appKey);
    url.append("&appsecret=").append(appSecret);
    String result = null;
    try {
    result = HttpHelper.sendGet(url.toString());
    } catch (IOException e) {
    result = ReturnUtil.result("-1",
    “请求accessTokenc出错!appKey:” + appKey + “,appSecret:” + appSecret + “异常信息:” + e);
    }
    System.out.println(“appKey:” + appKey + “,appSecret:” + appSecret + “,result:” + result);
    return JsonUtil.getJsonNode(result).get(“access_token”).asText();
    }

    private static String requestJsapiTicket(String accessToken) {
    StringBuffer url = new StringBuffer(TICKET_URL);
    url.append("?access_token=").append(accessToken);
    String result = null;
    try {
    result = HttpHelper.sendGet(url.toString());
    } catch (IOException e) {
    result = ReturnUtil.result("-1", “请求JsapiTicket出错!accessToken:” + accessToken + “异常信息:” + e);
    }
    System.out.println(“accessToken:” + accessToken + “,result:” + result);
    return JsonUtil.getJsonNode(result).get(“ticket”).asText();
    }

    private static String bytesToHex(byte[] hash) {
    Formatter formatter = new Formatter();
    for (byte b : hash) {
    formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
    }

    /**

    • 获取用户信息
    • @param code
    •        用户相应的临时code
      
    • @param token
    •        根据相应corpid和corpsecret生成的access_token
      
    • @return 用户ID等相关信息
      /
      public static String getUserInfo(String code, String accessToken) {
      StringBuffer url = new StringBuffer(USER_INFO_URL);
      url.append("?access_token=").append(accessToken);
      url.append("&code=").append(code);
      String result = null;
      try {
      result = HttpHelper.sendGet(url.toString());
      } catch (IOException e) {
      result = ReturnUtil.result("-1", “请求User信息出错!code:” + code + “异常信息:” + e);
      }
      return result;
      }
      /
      *
    • 获取用户详细信息
    • @param userid 在某个corpid下的唯一用户userid
    • @param accessToken 据相应corpid和corpsecret生成的access_token
    • @return
      */
      public static String getUser(String userid, String accessToken) {
      StringBuffer url = new StringBuffer(USER_ALL_URL);
      url.append("?access_token=").append(accessToken);
      url.append("&userid=").append(userid);
      String result = null;
      try {
      result = HttpHelper.sendGet(url.toString());
      } catch (IOException e) {
      result = ReturnUtil.result("-1", “请求User信息出错!userid:” + userid + “异常信息:” + e);
      }
      return result;
      }

}

前端代码如下:

钉钉微应用免登陆

<script type="text/javascript">//可以不要:01==>>startvar _config = null;$.ajax({type : "POST",url : "/config",dataType : "json",contentType : "application/json;charset=utf-8",async : false,data : "iNoI123s22",success : function(data) {// alert(data+"1、data")_config = data;// alert(_config+"2、_config")}});dd.config({agentId : _config.agentId, // 必填,微应用IDcorpId : _config.corpId,//必填,企业IDtimeStamp : _config.timestamp, // 必填,生成签名的时间戳nonceStr : _config.nonceStr, // 必填,生成签名的随机串signature : _config.sign, // 必填,签名type:0,   //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0jsApiList : ['runtime.info','device.notification.prompt','biz.chat.pickConversation','device.notification.confirm','device.notification.alert','device.notification.prompt','biz.chat.open','biz.util.open','biz.user.get','biz.contact.choose','biz.telephone.call','biz.util.uploadImage','biz.ding.post']});//可以不要:01==>>end// alert("111112222");dd.error(function(r){alert("error:"+JSON.stringify(r));})dd.ready(function() {//可以不要:02==>>startdd.device.notification.showPreloader({text : "正在获取当前用户信息 ...",showIcon : true,onSuccess : function(result) {},onFail : function(err) {}});//可以不要:02==>>end//获取code//必须dd.runtime.permission.requestAuthCode({corpId : _config.corpId,onSuccess : function(result) {var code = result.code;// alert("code:"+code);$("#code").text("钉钉传向后台CODE:" + code);getUserInfo(code);},onFail : function(err) {alert('出错了, ' + err);}});});//拿到code以后剩下的都可以不要:03==>>startfunction getUserInfo(code) {$.ajax({type : "GET",url : "/userinfo?code=" + code,async : false,dataType : 'json',contentType : "application/json;charset=utf-8",success : (function(response) {$("#userid").text("获取的用户信息:" + JSON.stringify(response));dd.device.notification.hidePreloader({ //隐藏加载中onSuccess : function(result) {},onFail : function(err) {}});dd.device.notification.vibrate({//手机震动duration : 1000,onSuccess : function(result) {},onFail : function(err) {}});// 显示用户简略信息displayInfo(response);}),});}function displayInfo(response) {dd.device.notification.actionSheet({//actionSheet弹窗title : "当前用户信息",cancelButton : '关闭',//取消按钮文本otherButtons : [ 'userid: ' + response.userid, 'deviceId: ' + response.deviceId, 'is_sys: ' + response.is_sys, 'sys_level: ' + response.sys_level ],//其他按钮列表onSuccess : function(result) {$.ajax({type : "GET",url : "/user?userid=" + response.userid,async : false,dataType : 'json',contentType : "application/json;charset=utf-8",success : (function(data) {// $("#userall").text("用户信息详细:" + JSON.stringify(data));//显示用户详细信息displayall(data);alert(data.mobile);})});},onFail : function(err) {}});}function displayall(data) {var all = [];all.push("userID:" + data.userid);// all.push("openID:" + data.openid);all.push("unionid:" + data.unionid);// all.push("dingId:" + data.dingId);all.push("name:" + data.name);all.push("mobile:" + data.mobile);all.push("isBoss:" + data.isBoss);all.push("active:" + data.active);all.push("isAdmin:" + data.isAdmin);all.push("isSenior:" + data.isSenior);all.push("department:" + data.department);all.push("isLeaderInDepts:" + data.isLeaderInDepts);dd.device.notification.actionSheet({title : "详细信息", //标题cancelButton : '关闭', //取消按钮文本otherButtons : all,onSuccess : function(result) {},onFail : function(err) {}})}//拿到code以后剩下的都可以不要:03==>>start
</script>

到这里基本OK了,这两个为主要代码,还有其他的封装页面比较简单,就不贴出来了

钉钉微应用的免登录(前后端)相关推荐

  1. 企业内部钉钉H5微应用(免登录)Spring Boot项目实战

    文章目录 前言 一.准备工作 1.开发前准备: 2.钉钉微应用的免登流程: 二.开放过程 1.新建企业号 2.创建H5微应用 3.项目编码 三.微应用配置 四.启动项目后即可访问,应用截图 总结 前言 ...

  2. [整站源码]thinkphp美肤微形美容仪器网站模板+前后端源码

    模板介绍: 本模板自带eyoucms内核,无需再下载eyou系统,原创设计.手工书写DIV+CSS,完美兼容IE7+.Firefox.Chrome.360浏览器等:主流浏览器:结构容易优化:多终端均可 ...

  3. 微服务背景下的前后端分离

    Web前后端分离 前后端开发模式已经成为一种"政治正确"了.当然,这种模式的确是分工明确.开发高效的.同时,与前后端分离开发模式相对应的,实际是FULL STACK--全栈开发模式 ...

  4. 微信第三方登录前后端分离实现思路

    微信第三方登录前后端分离实现思路 前端实现 这里说一下前后端的思路,页面加载时声明一个变量state='时间戳+6位随机数', 前端路径生成二维码, 其中有个state参数需要我们传递,这个参数你传什 ...

  5. (详解)钉钉接口,PC端微应用,免登录及获取当前用户信息

    1.用了两天的时间,一直在研究微应用的,免登录及获取用户信息这一块. 但是钉钉官网写的太繁杂了,看了一天,硬是没看明白,最后,硬着头皮,一点点查资料,借鉴别人的代码,终于 研究 出来了,为了防止 年轻 ...

  6. 钉钉H5微应用开发免登以及接口调试

    钉钉H5微应用开发以及接口调试 企业内部应用免登 https://open.dingtalk.com/document/orgapp-server/enterprise-internal-applic ...

  7. 干货 | 万字长文全面解析GraphQL,携程微服务背景下的前后端数据交互方案

    作者简介 古映杰,携程研发高级经理,负责前端框架和基础设施的设计.研发与维护.开源项目react-lite和react-imvc作者. 前言 随着多终端.多平台.多业务形态.多技术选型等各方面的发展, ...

  8. php前后端分离登录,前后端分离下如何登录

    1 Web登录涉及到知识点 1.1 HTTP无状态性HTTP是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的.当然它知道是哪个客户端地址发过来的,但是对于 ...

  9. 首个直播商城,拼团商城,小程序商城的微服务分布式框架,前后端分离

    简介: sdb mall 项目说明 sdb是一个轻量级的在renren-fast基础上利用jfinal架构二次开发的一个极速二次开发直播,拼团商城框架,前后端分离的Java快速开发平台,C端采用微信小 ...

最新文章

  1. 【技术交流】让我们来谈一谈多线程和并发任务
  2. spingmvc-参数传递
  3. html表单提交前验证,jquery表单提交前实现同步验证(附代码)
  4. 关于Vue中计算属性computed和methods属性的区别,你了解多少呢
  5. java mysql nclob_java语言操作Oracle数据库中的CLOB数据类型 (转)
  6. 热门开源多媒体库 PJSIP 被爆5个内存损坏漏洞
  7. 【BZOJ4205】卡牌配对
  8. Google亲儿子 Nexus/Pixel 手机刷机Root之旅
  9. javascript将页面设为首页代码大全
  10. vue、四级联动(省市区街道)
  11. 修改网络设备在路由器中显示名称
  12. 计算机网络初探(ip协议)
  13. html5 保存 搜索历史,前端实现搜索记录功能也就是天猫app历史记录存储方便浏览 - 今天的代码你撸了嘛...
  14. 文件服务器属于固定资产吗,服务器内存属于固定资产吗
  15. linux deploy连接ssh失败,ubuntu – Jenkins发布ssh成功连接服务器但是put文件失败
  16. 商标权的取得方式有哪些
  17. 【计算机网络】虚拟IP原理
  18. taro 小程序编译在标签上px转rpx的api
  19. 为什么使用计算机辅助翻译工具中文译文,TCloud计算机辅助翻译工具
  20. java 视频转码 视频压缩

热门文章

  1. 古董电脑清灰+双系统安装 part1
  2. JAVA多线程+事务进行批量新增
  3. 俄罗斯欲推国产应用取代 Google Play
  4. html桌面图标样式,Win7桌面图标样式怎么修改和还原|Win7修改和还原桌面图标样式的方法...
  5. Some objects were not cleaned up when closing the scene.
  6. 路由器交换机基本配置命令
  7. 推荐系统的评测指标新颖性和惊喜度的区别
  8. PT网站显示阻断页面,无法登录进去怎么办?
  9. iPhone上的CPU架构,核数以及运行内存
  10. 我与python约个会:12程序编程基础6:选择和循环