前端
<script type="text/javascript">
const APP_ID = '${DING_APP_ID}';
const APP_SECRET = '${DING_APP_SECRET}';
const REDIRECT_URI = '${DING_REDIRECT_URI}';
const GOTO_url = "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid="+APP_ID+"&response_type=code&scope=snsapi_login&state=STATE&redirect_uri="+REDIRECT_URI;
/*
* 解释一下goto参数,参考以下例子:
* var url = encodeURIComponent('http://localhost.me/index.php?test=1&aa=2');
* var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=appid&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+url)
*/
$(function () {
var obj = DDLogin({
id:"login_container",//这里需要你在自己的页面定义一个HTML标签并设置id,例如或
goto: encodeURIComponent(GOTO_url), //请参考注释里的方式
style: "border:none;background-color:#FFFFFF;",
width : "365",
height: "400"
});
console.log(APP_ID,APP_SECRET,REDIRECT_URI);
var handleMessage = function (event) {
var origin = event.origin;
console.log("origin", event.origin);
if( origin == "https://login.dingtalk.com" ) { //判断是否来自ddLogin扫码事件。
var loginTmpCode = event.data;
//获取到loginTmpCode后就可以在这里构造跳转链接进行跳转了
console.log("loginTmpCode", loginTmpCode);
window.location.href =
"https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid="+APP_ID+"&response_type=code&scope=snsapi_login&state=STATE&redirect_uri="+REDIRECT_URI+"&loginTmpCode="+loginTmpCode;
}
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', handleMessage, false);
} else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onmessage', handleMessage);
}
})
</script>
后端 APP_ID:扫码登录的app_id,APP_ID2:企业的APP_ID
@Service
public class DingDingService {
/**
* 根据 授权码 获取用户信息
* @param code
* @return
* @throws ApiException
*/
public ControlClerk getLoginUser(String code) throws ApiException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
String accessToken = this.getAccessToken();
String unionId = this.getUnionId(code);
String userIdByUnionId = this.getUserIdByUnionId(unionId, accessToken);
ControlClerk user = this.getUserByUserId(userIdByUnionId, accessToken);
return user;
}
/**
* 根据 userId 获取用户信息
* @param userId
* @param accessToken
* @return
* @throws ApiException
*/
public ControlClerk getUserByUserId(String userId,String accessToken) throws ApiException {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
OapiUserGetRequest request = new OapiUserGetRequest();
request.setUserid(userId);
request.setHttpMethod("GET");
OapiUserGetResponse response = client.execute(request, accessToken);
if (response.getErrcode() !=0 ){
throw new RuntimeException(response.getErrmsg());
}
ControlClerk clerk = new ControlClerk();
clerk.setUserId(response.getUserid());
clerk.setUserName(response.getName());
return clerk;
}
/**
根据授权码获取 unionId
* @param tmpAuthCode
* @return
* @throws ApiException
*/
public String getUnionId(String tmpAuthCode) throws ApiException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
String timestamp = String.valueOf(System.currentTimeMillis());
String signature = this.getSignature(timestamp);
DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature="+signature+"×tamp="+timestamp+"&accessKey="+SysConfigCache.getString("DING_APP_ID"));
OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
req.setTmpAuthCode(tmpAuthCode);
OapiSnsGetuserinfoBycodeResponse response = client.execute(req, SysConfigCache.getString("DING_APP_ID"), SysConfigCache.getString("DING_APP_SECRET2"));
if (response.getErrcode() !=0 ){
throw new RuntimeException(response.getErrmsg());
}
return response.getUserInfo().getUnionid();
}
/**
* 根据 unionId 获取userId
* @return
* @throws ApiException
*/
public String getUserIdByUnionId(String unionId,String accessToken) throws ApiException {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getUseridByUnionid");
OapiUserGetUseridByUnionidRequest request = new OapiUserGetUseridByUnionidRequest();
request.setUnionid(unionId);
request.setHttpMethod("GET");
OapiUserGetUseridByUnionidResponse response = client.execute(request, accessToken);
if (response.getErrcode() !=0 ){
throw new RuntimeException(response.getErrmsg());
}
return response.getUserid();
}
/**
* 获取 accessToken
* @return
* @throws ApiException
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws UnsupportedEncodingException
*/
public String getAccessToken() throws ApiException {
DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
OapiGettokenRequest request = new OapiGettokenRequest();
request.setAppkey(SysConfigCache.getString("DING_APP_ID2"));
request.setAppsecret(SysConfigCache.getString("DING_APP_SECRET2"));
request.setHttpMethod("GET");
OapiGettokenResponse response = client.execute(request);
if (response.getErrcode() !=0 ){
throw new RuntimeException(response.getErrmsg());
}
return response.getAccessToken();
}
/**
* 签名算法
* @param timestamp
* @return
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
* @throws InvalidKeyException
*/
public String getSignature(String timestamp) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
// 根据timestamp, appSecret计算签名值
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(SysConfigCache.getString("DING_APP_SECRET").getBytes("UTF-8"), "HmacSHA256"));
byte[] signatureBytes = mac.doFinal(timestamp.getBytes("UTF-8"));
String signature = new String(Base64.encodeBase64(signatureBytes));
String urlEncodeSignature = urlEncode(signature);
return urlEncodeSignature;
}
// encoding参数使用utf-8
public String urlEncode(String value) {
if (value == null) {
return "";
}
try {
String encoded = URLEncoder.encode(value,"utf-8");
return encoded.replace("+", "%20").replace("*", "%2A")
.replace("~", "%7E").replace("/", "%2F");
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("FailedToEncodeUri", e);
}
}
}