24282 2 years ago
parent
commit
06bf4e88c8

+ 45 - 6
hx-dingding/src/main/java/com/fjhx/controller/DingController.java

@@ -2,12 +2,18 @@ package com.fjhx.controller;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.dingtalkoauth2_1_0.models.GetCorpAccessTokenResponseBody;
+import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
 import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
 import com.fjhx.constant.Constant;
+import com.fjhx.entity.dto.GetUserTokenDto;
+import com.fjhx.utils.DingUtil;
 import com.ruoyi.common.annotation.NonInterception;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.LinkedHashMap;
+
 @Slf4j
 @RestController
 @RequestMapping("/open")
@@ -21,7 +27,7 @@ public class DingController {
     /**
      * 创建应用,验证回调URL变更有效事件(第一次保存回调URL之后)
      */
-    private static final String EVENT_CHECK_UPADTE_SUITE_URL = "check_update_suite_url";
+    private static final String EVENT_CHECK_UPDATE_SUITE_URL = "check_update_suite_url";
 
     /**
      * suite_ticket推送事件
@@ -33,6 +39,16 @@ public class DingController {
      */
     private static final String EVENT_TMP_AUTH_CODE = "tmp_auth_code";
 
+    /**
+     * 高优先级数据,激活应用等
+     */
+    private static final String EVENT_SYNC_HTTP_PUSH_HIGH = "SYNC_HTTP_PUSH_HIGH";
+
+    /**
+     * 普通优先级数据,例如通讯录变更
+     */
+    private static final String EVENT_SYNC_HTTP_PUSH_MEDIUM = "SYNC_HTTP_PUSH_MEDIUM";
+
     @NonInterception
     @PostMapping(value = "/dingCallback")
     public Object dingCallback(
@@ -44,36 +60,46 @@ public class DingController {
         String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body;
 
         try {
-            log.info("begin callback:" + params);
-            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(Constant.TOKEN, Constant.ENCODING_AES_KEY, Constant.SUITE_KEY);
+            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(
+                    Constant.TOKEN, Constant.ENCODING_AES_KEY, Constant.SUITE_KEY);
 
             // 从post请求的body中获取回调信息的加密数据进行解密处理
             String encrypt = body.getString("encrypt");
             String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt);
             JSONObject callBackContent = JSON.parseObject(plainText);
 
-            log.info("callBackContent:{}", callBackContent.toJSONString());
-
             // 根据回调事件类型做不同的业务处理
             String eventType = callBackContent.getString("EventType");
             switch (eventType) {
                 case EVENT_CHECK_CREATE_SUITE_URL:
                     log.info("验证新创建的回调URL有效性: " + plainText);
                     break;
-                case EVENT_CHECK_UPADTE_SUITE_URL:
+
+                case EVENT_CHECK_UPDATE_SUITE_URL:
                     log.info("验证更新回调URL有效性: " + plainText);
                     break;
+
                 case EVENT_SUITE_TICKET:
                     // suite_ticket用于用签名形式生成accessToken(访问钉钉服务端的凭证),需要保存到应用的db。
                     // 钉钉会定期向本callback url推送suite_ticket新值用以提升安全性。
                     // 应用在获取到新的时值时,保存db成功后,返回给钉钉success加密串(如本demo的return)
                     log.info("应用suite_ticket数据推送: " + plainText);
                     break;
+
                 case EVENT_TMP_AUTH_CODE:
                     // 本事件应用应该异步进行授权开通企业的初始化,目的是尽最大努力快速返回给钉钉服务端。用以提升企业管理员开通应用体验
                     // 即使本接口没有收到数据或者收到事件后处理初始化失败都可以后续再用户试用应用时从前端获取到corpId并拉取授权企业信息,进而初始化开通及企业。
                     log.info("企业授权开通应用事件: " + plainText);
                     break;
+
+                case EVENT_SYNC_HTTP_PUSH_HIGH:
+                    log.info("高优先级数据:" + plainText);
+                    break;
+
+                case EVENT_SYNC_HTTP_PUSH_MEDIUM:
+                    log.info("普通优先级数据:" + plainText);
+                    break;
+
                 default:
                     // 其他类型事件处理
                     log.info("其他类型事件: " + plainText);
@@ -88,4 +114,17 @@ public class DingController {
         }
 
     }
+
+    @PostMapping(value = "/dingApi/getUserToken")
+    public LinkedHashMap<String, Object> getUserToken(@RequestBody GetUserTokenDto dto) {
+        GetCorpAccessTokenResponseBody corpAccessToken = DingUtil.getCorpAccessToken(dto.getCorpId());
+        OapiV2UserGetuserinfoResponse.UserGetByCodeResponse userInfo = DingUtil.getUserInfo(corpAccessToken.getAccessToken(), dto.getCode());
+
+        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
+        map.put("tokenInfo", corpAccessToken);
+        map.put("userInfo", userInfo);
+        return map;
+    }
+
+
 }

+ 14 - 0
hx-dingding/src/main/java/com/fjhx/entity/dto/GetUserTokenDto.java

@@ -0,0 +1,14 @@
+package com.fjhx.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class GetUserTokenDto {
+
+    private String code;
+
+    private String corpId;
+
+}

+ 27 - 53
hx-dingding/src/main/java/com/fjhx/utils/DingUtil.java

@@ -1,17 +1,16 @@
 package com.fjhx.utils;
 
 import cn.hutool.core.util.StrUtil;
-import com.aliyun.dingtalkcontact_1_0.models.GetUserHeaders;
-import com.aliyun.dingtalkcontact_1_0.models.GetUserResponseBody;
-import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenRequest;
-import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenResponseBody;
+import com.aliyun.dingtalkoauth2_1_0.Client;
+import com.aliyun.dingtalkoauth2_1_0.models.GetCorpAccessTokenRequest;
+import com.aliyun.dingtalkoauth2_1_0.models.GetCorpAccessTokenResponseBody;
 import com.aliyun.tea.TeaException;
 import com.aliyun.teaopenapi.models.Config;
-import com.aliyun.teautil.models.RuntimeOptions;
 import com.dingtalk.api.DefaultDingTalkClient;
 import com.dingtalk.api.DingTalkClient;
 import com.dingtalk.api.request.OapiV2UserGetuserinfoRequest;
 import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
+import com.fjhx.constant.Constant;
 import com.ruoyi.common.exception.ServiceException;
 import com.taobao.api.ApiException;
 import lombok.extern.slf4j.Slf4j;
@@ -23,37 +22,29 @@ import lombok.extern.slf4j.Slf4j;
  * <p>
  * <a href="https://open.dingtalk.com/document/isvapp/basic-concepts"> 基础概念 </a>
  * <a href="https://open.dingtalk.com/document/isvapp/api-overview"> 钉钉api总览 </a>
- * <a href="https://open.dingtalk.com/document/isvapp/obtain-identity-credentials"> 获取登录用户的访问凭证 </a>
+ * <a href="https://open.dingtalk.com/document/isvapp/third-party-enterprise-application-logon-free"> 免登流程 </a>
  * </p>
  */
 
 @Slf4j
 public class DingUtil {
 
-    public static void main(String[] args) {
-        GetUserTokenResponseBody userToken = DingUtil.getUserToken("9688f43aebe531238c9398fa5004c7a7");
-        String accessToken = userToken.getAccessToken();
-    }
-
-    private static final String SUITE_KEY = "suite8j0xog63udtsaq7g";
-    private static final String SUITE_SECRET = "NdbWhD6Iu9n5h-3IKXeepmPwmcFbOw9Em7UeiJKyq3_Wa8LgmJ-G6b8SmsOJMrMc";
-
     /**
-     * 获取用户token
-     *
-     * <p>
-     * https://open.dingtalk.com/document/isvapp/obtain-user-token
+     * 获取第三方应用授权企业的accessToken
+     * https://open.dingtalk.com/document/isvapp/obtain-the-access_token-of-the-authorized-enterprise
      */
-    public static GetUserTokenResponseBody getUserToken(String code) {
-        GetUserTokenRequest getUserTokenRequest = new GetUserTokenRequest()
-                .setClientId(SUITE_KEY)
-                .setClientSecret(SUITE_SECRET)
-                .setCode(code)
-                .setGrantType("authorization_code");
+    public static GetCorpAccessTokenResponseBody getCorpAccessToken(String corpId) {
+
+        GetCorpAccessTokenRequest getCorpAccessTokenRequest = new GetCorpAccessTokenRequest()
+                .setSuiteKey(Constant.SUITE_KEY)
+                .setSuiteSecret(Constant.SUITE_SECRET)
+                .setAuthCorpId(corpId)
+                .setSuiteTicket("Kn3hJvJR34e8rUEob0W7nqxK2YHqobAyPsuIQXYR35SsJMp6rE5XQBz9nwXTrJRZaVmXc4z9KjYkzXdkUdS8O3");
 
         try {
-            com.aliyun.dingtalkoauth2_1_0.Client client = getClient2();
-            return client.getUserToken(getUserTokenRequest).getBody();
+            Client client = getClient2();
+            GetCorpAccessTokenResponseBody corpAccessToken = client.getCorpAccessToken(getCorpAccessTokenRequest).getBody();
+            return corpAccessToken;
         } catch (Exception e) {
 
             TeaException teaException;
@@ -74,44 +65,27 @@ public class DingUtil {
                 log.error("钉钉授权认证失败", teaException);
                 throw new ServiceException("发生未知异常,钉钉授权认证失败");
             }
+
         }
     }
 
     /**
-     * 获取用户信息
-     *
-     * <p>
+     * 通过免登码获取用户信息
      * https://open.dingtalk.com/document/isvapp/obtain-the-userid-of-a-user-by-using-the-log-free
      */
-    public static OapiV2UserGetuserinfoResponse.UserGetByCodeResponse getUserInfo(String code, String accessToken) {
-        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
-        OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
-        req.setCode(code);
-
+    public static OapiV2UserGetuserinfoResponse.UserGetByCodeResponse getUserInfo(String corpAccessToken, String code) {
         try {
-            OapiV2UserGetuserinfoResponse rsp = client.execute(req, accessToken);
+            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
+            OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
+            req.setCode(code);
+            OapiV2UserGetuserinfoResponse rsp = client.execute(req, corpAccessToken);
             return rsp.getResult();
         } catch (ApiException e) {
-            String message = "钉钉获取用户信息失败: code:" + e.getErrCode() + ",message:" + e.getErrMsg();
-            log.error(message);
-            throw new ServiceException(message);
+            log.error("通过免登码获取用户信息失败");
+            throw new ServiceException("通过免登码获取用户信息失败");
         }
     }
 
-    /**
-     * 获取用户个人信息
-     *
-     * <p>
-     * https://open.dingtalk.com/document/isvapp/tutorial-enabling-login-to-third-party-websites
-     */
-    public GetUserResponseBody getUserinfo(String accessToken) throws Exception {
-        com.aliyun.dingtalkcontact_1_0.Client client = getClient1();
-        GetUserHeaders getUserHeaders = new GetUserHeaders();
-        getUserHeaders.setXAcsDingtalkAccessToken(accessToken);
-
-        // 获取用户个人信息,如需获取当前授权人的信息,unionId参数必须传me
-        return client.getUserWithOptions("me", getUserHeaders, new RuntimeOptions()).getBody();
-    }
 
     private static com.aliyun.dingtalkcontact_1_0.Client getClient1() throws Exception {
         Config config = new Config();
@@ -120,7 +94,7 @@ public class DingUtil {
         return new com.aliyun.dingtalkcontact_1_0.Client(config);
     }
 
-    public static com.aliyun.dingtalkoauth2_1_0.Client getClient2() throws Exception {
+    private static com.aliyun.dingtalkoauth2_1_0.Client getClient2() throws Exception {
         Config config = new Config();
         config.protocol = "https";
         config.regionId = "central";