最近做了个钉钉企业内部微应用的项目。记录下自己的心得。
首先根据官方文档明白免登流程
但是,最近更新的开发者平台,已经不在提供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("×tamp=").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
- 1
- @param token
-
根据相应corpid和corpsecret生成的access_token
- 1
- @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==>>start var _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, // 必填,微应用ID corpId : _config.corpId,//必填,企业ID timeStamp : _config.timestamp, // 必填,生成签名的时间戳 nonceStr : _config.nonceStr, // 必填,生成签名的随机串 signature : _config.sign, // 必填,签名 type:0, //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0 jsApiList : [ '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==>>start dd.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==>>start function 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了,这两个为主要代码,还有其他的封装页面比较简单,就不贴出来了转自:https://blog.csdn.net/weixin_44685631/article/details/90240216