OA集成钉钉开发——第四篇——微应用开发
2016-12-21 00:00
197 查看
前一篇我们说到从钉钉中登录微应用,因为我们是从微应用的中的入口进入的,那么我们项目中就不需要设置登录,注册,我们通过钉钉就可以拿到你的唯一标识,这个标识在我们的组织机构中,也就是数据库中提前就会从阿里云中down下来,这样就是 钉钉的免登陆了!
相关代码实现:
我的web项目使用java,springmvc_mybatis实现。
我在钉钉的微应用中设置的入口的URL:项目名+/order/change_order_apply_page.do
controller中代码:
其中 String config= AuthHelper.getConfig(request);
AuthHelper是手动封装的工具类:
相关钉钉数据在java 后台中进行http请求拿到
返回到我的jsp界面中,在我们JSP界面中我引入了钉钉的JS
界面初始化时 我会加载一段JS:其中angentID 是钉钉分给你微应用的ID ,重复貌似也没事。
dd.ready中我会向后台传入code码:
其中DDUtil,GlobalConstant是手动封装的类;
DDUtil.getUserID(code);这句代码是通过code向钉钉服务器请求该用户的staffuserid 也就我们所说的用户的唯一标识;再从我们数据库获取用户的相关信息,存入session中。
这是就是我的免登陆流程!
相关代码实现:
我的web项目使用java,springmvc_mybatis实现。
我在钉钉的微应用中设置的入口的URL:项目名+/order/change_order_apply_page.do
controller中代码:
/** * 项目变更申请界面 * @return */ @RequestMapping("/change_order_apply_page.do") public ModelAndView change_order_apply_page(HttpServletRequest request){ ModelAndView mav = new ModelAndView(); String config= AuthHelper.getConfig(request); System.out.println("config:"+config); request.setAttribute("config", config); mav.setViewName("order/change_order_apply"); return mav; }
其中 String config= AuthHelper.getConfig(request);
AuthHelper是手动封装的工具类:
import com.alibaba.fastjson.JSONObject; import com.ddSdk.base.Env; import com.ddSdk.base.OApiException; import com.ddSdk.base.OApiResultException; import com.ddSdk.utils.FileUtils; import com.ddSdk.utils.HttpHelper; import com.dingtalk.open.client.ServiceFactory; import com.dingtalk.open.client.api.model.corp.JsapiTicket; import com.dingtalk.open.client.api.service.corp.CorpConnectionService; import com.dingtalk.open.client.api.service.corp.JsapiService; import com.dingtalk.open.client.common.SdkInitException; import com.dingtalk.open.client.common.ServiceException; import com.dingtalk.open.client.common.ServiceNotExistException; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.Formatter; import java.util.Timer; public class AuthHelper { // public static String jsapiTicket = null; // public static String accessToken = null; public static Timer timer = null; // 调整到1小时50分钟 public static final long cacheTime = 7200; public static long currentTime = 0 + cacheTime + 1; public static long lastTime = 0; public static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /* * 在此方法中,为了避免频繁获取access_token, * 在距离上一次获取access_token时间在两个小时之内的情况, * 将直接从持久化存储中读取access_token * * 因为access_token和jsapi_ticket的过期时间都是7200秒 * 所以在获取access_token的同时也去获取了jsapi_ticket * 注:jsapi_ticket是在前端页面JSAPI做权限验证配置的时候需要使用的 * 具体信息请查看开发者文档--权限验证配置 */ public static String getAccessToken() throws OApiException { long curTime = System.currentTimeMillis(); JSONObject accessTokenValue = (JSONObject) FileUtils.getValue("accesstoken", Env.CORP_ID); String accToken = ""; String jsTicket = ""; JSONObject jsontemp = new JSONObject(); 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); // save accessToken JSONObject jsonAccess = new JSONObject(); jso 7fe0 ntemp.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 (SdkInitException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ServiceNotExistException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { return accessTokenValue.getString("access_token"); } return accToken; } // 正常的情况下,jsapi_ticket的有效期为7200秒,所以开发者需要在某个地方设计一个定时器,定期去更新jsapi_ticket 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 (SdkInitException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ServiceNotExistException e) { // TODO Auto-generated catch block e.printStackTrace(); } return jsTicket; } else { return jsTicketValue.getString("ticket"); } } public static String sign(String ticket, String nonceStr, long timeStamp, String url) throws OApiException { String plain = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + String.valueOf(timeStamp) + "&url=" + url; try { MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); sha1.reset(); sha1.update(plain.getBytes("UTF-8")); return bytesToHex(sha1.digest()); } catch (NoSuchAlgorithmException e) { throw new OApiResultException(e.getMessage()); } catch (UnsupportedEncodingException e) { throw new OApiResultException(e.getMessage()); } } 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; } public static String getConfig(HttpServletRequest request) { String urlString = request.getRequestURL().toString(); String queryString = request.getQueryString(); String queryStringEncode = null; String url; if (queryString != null) { queryStringEncode = URLDecoder.decode(queryString); url = urlString + "?" + queryStringEncode; } else { url = urlString; } String nonceStr = "abcdefg"; long timeStamp = System.currentTimeMillis() / 1000; String signedUrl = url; String accessToken = null; String ticket = null; String signature = null; String agentid = null; try { accessToken = AuthHelper.getAccessToken(); ticket = AuthHelper.getJsapiTicket(accessToken); signature = AuthHelper.sign(ticket, nonceStr, timeStamp, signedUrl); agentid = ""; } catch (OApiException e) { // TODO Auto-generated catch block e.printStackTrace(); } String configValue = "{jsticket:'" + ticket + "',signature:'" + signature + "',nonceStr:'" + nonceStr + "',timeStamp:'" + timeStamp + "',corpId:'" + Env.CORP_ID + "',agentid:'" + agentid+ "'}"; System.out.println(configValue); return configValue; } public static String getSsoToken() throws OApiException { String url = "https://oapi.dingtalk.com/sso/gettoken?corpid=" + Env.CORP_ID + "&corpsecret=" + Env.SSO_Secret; JSONObject response = HttpHelper.httpGet(url); String ssoToken; if (response.containsKey("access_token")) { ssoToken = response.getString("access_token"); } else { throw new OApiResultException("Sso_token"); } return ssoToken; } }
相关钉钉数据在java 后台中进行http请求拿到
返回到我的jsp界面中,在我们JSP界面中我引入了钉钉的JS
<script type="text/javascript" src="http://g.alicdn.com/ilw/ding/0.7.3/scripts/dingtalk.js"></script>
界面初始化时 我会加载一段JS:其中angentID 是钉钉分给你微应用的ID ,重复貌似也没事。
/*权限验证配置所需的信息 */ var config =<%=request.getAttribute("config")%>; //当前用户 var nowUser=null; //用户授权码 var code=null; /* $(document).ready(function(){ $.alert(config); }); */ //配置钉钉jsapi dd.config({ agentId : "38433641", corpId : config.corpId, timeStamp : config.timeStamp, nonceStr : config.nonceStr, signature : config.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.permission.requestAuthCode({ corpId : config.corpId, //请求 code onSuccess : function(info) { //存储用户信息 $.post("<%=path%>/order/login.do",{"code":info.code}); //向后台传入code }, onFail : function(err) { alert('fail: ' + JSON.stringify(err)); } }); });
dd.ready中我会向后台传入code码:
/** * 项目变更申请界面 * @return */ @RequestMapping("/login.do") public void login(HttpServletRequest request,String code){ String staffUserId=DDUtil.getUserID(code); System.out.println("staffUserId:"+staffUserId); //从数据库中获得该员工的所有信息 StaffInfo staffInfo= iStaffInfoService.selectStaffByID(staffUserId); //在当前回话session中存储相关信息 request.getSession().setAttribute(GlobalConstant.user_staffId, staffInfo.getStaffId()); request.getSession().setAttribute(GlobalConstant.user_department, staffInfo.getDepartment()); request.getSession().setAttribute(GlobalConstant.user_staff_user_id,staffInfo.getStaffUserId()); request.getSession().setAttribute(GlobalConstant.user_name,staffInfo.getName()); }
其中DDUtil,GlobalConstant是手动封装的类;
DDUtil.getUserID(code);这句代码是通过code向钉钉服务器请求该用户的staffuserid 也就我们所说的用户的唯一标识;再从我们数据库获取用户的相关信息,存入session中。
这是就是我的免登陆流程!
相关文章推荐
- OA集成钉钉开发——第三篇——添加微应用
- 工作流平台集成微软WSS开发大型OA项目解决方案
- ZF开发的PHP应用与传统PHP应用集成的方法
- 图解应用集成开发环境设计GUI程序-2
- ubuntu 10.04 应用eclipse 搭建 RTEMS 应用程序集成开发环境
- 系统集成应用及快速开发平台
- Extjst系统集成与应用开发平台(一)
- 图解应用集成开发环境设计GUI程序-1
- Extjst系统集成与应用开发平台(一)
- Android应用集成开发环境,强烈推荐使用
- ZF开发的PHP应用与传统PHP应用集成的方法
- 使用Eclipse开发J2EE应用,集成Eclipse, Lomboz和JBoss
- 数据库开发的持续集成 - Liquibase的简介和应用
- vaadin与grails的集成应用开发
- JBoss4 应用服务器Web开发人员参考手册(9):与Apache集成
- 集成Eclipse和InforWeb开发第一个Struts应用
- 使用 Sql 2005 中集成CLR功能开发基于C#的应用
- 如何实现 Websphere Portal 6.0 与 Cognos 8 集成应用开发
- unity3d与eclipse集成开发android应用
- Extjst系统集成与应用开发平台(一)