Procházet zdrojové kódy

钉钉扫码登录修改

yusm před 3 týdny
rodič
revize
8097e128a5

+ 0 - 28
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DingTalkController.java

@@ -107,34 +107,6 @@ public class DingTalkController {
         return modelAndView;
     }
 
-    /*@GetMapping("/getSign")
-    public HttpRespMsg getSign() {
-        HttpRespMsg msg = new HttpRespMsg();
-        try {
-            String timestamp = String.valueOf(System.currentTimeMillis());
-            System.out.println("timestamp=="+timestamp);
-            String stringToSign = timestamp + "\n" + "o-TWFLkFe8YbJsa_025JOj_JEWydP5GR3eigt1Yn1rtx5dTcryTJiSA6KEih3Bi4";
-            Mac mac = Mac.getInstance("HmacSHA256");
-            mac.init(new SecretKeySpec("o-TWFLkFe8YbJsa_025JOj_JEWydP5GR3eigt1Yn1rtx5dTcryTJiSA6KEih3Bi4".getBytes("UTF-8"), "HmacSHA256"));
-            byte[] signatureBytes = mac.doFinal(stringToSign.getBytes("UTF-8"));
-            String signature = new String(Base64.encodeBase64(signatureBytes));
-            if("".equals(signature)) {
-                msg.setError("生成签名失败");
-                return msg;
-            }
-            String encoded = URLEncoder.encode(signature, "UTF-8");
-            String urlEncodeSignature = encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
-
-            HashMap<String, String> map = new HashMap<>();
-            map.put("timestamp", timestamp);
-            map.put("sign", urlEncodeSignature);
-            msg.data=map;
-        } catch (Exception e) {
-            throw new RuntimeException("生成签名失败", e);
-        }
-        return msg;
-    }*/
-
 
 
     private HashMap getCompExpireInfo(Integer companyId) {

+ 70 - 115
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingTalkService.java

@@ -7,10 +7,7 @@ import com.management.platform.entity.DingTalkUserInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
@@ -24,6 +21,7 @@ import java.util.Base64;
 import java.util.HashMap;
 import java.util.Map;
 
+
 @Service
 public class DingTalkService {
     private static final Logger log = LoggerFactory.getLogger(DingTalkService.class);
@@ -41,36 +39,6 @@ public class DingTalkService {
         this.restTemplate = restTemplate;
     }
 
-    /**
-     * 使用临时授权码获取用户信息
-     */
-    public DingTalkUserInfo getUserInfoByCode(String code) {
-        // 1. 构造请求参数
-        String timestamp = String.valueOf(System.currentTimeMillis());
-        String signature = generateSignature(timestamp);
-        
-        // 2. 构造请求体
-        Map<String, String> requestBody = new HashMap<>();
-        requestBody.put("tmp_auth_code", code);
-        
-        // 3. 构造请求URL
-        String url = String.format("%s?accessKey=%s&timestamp=%s&signature=%s",
-                GET_USER_INFO_URL, dingTalkConfig.getAppId(), timestamp, signature);
-        
-        // 4. 发送请求
-        ResponseEntity<String> response = restTemplate.postForEntity(
-                url, 
-                new HttpEntity<>(requestBody, buildHeaders()),
-                String.class);
-        
-        // 5. 解析响应
-        JsonNode jsonNode = parseResponse(response.getBody());
-        JsonNode userInfo = jsonNode.get("user_info");
-        
-        // 6. 获取用户详细信息
-        String unionId = userInfo.get("unionid").asText();
-        return getUserDetail(unionId);
-    }
 
     /**
      * 使用临时授权码获取用户信息
@@ -81,100 +49,87 @@ public class DingTalkService {
         try {
             logger.info("开始获取用户OpenID,临时授权码: {}", code);
 
-            // 1. 构造请求参数
-            String timestamp = String.valueOf(System.currentTimeMillis());
-            String signature = generateSignature(timestamp);
-            logger.info("生成请求参数 - timestamp: {}, signature: {}", timestamp, signature);
-
-            // 2. 构造请求体
-            Map<String, String> requestBody = new HashMap<>();
-            requestBody.put("tmp_auth_code", code);
-            logger.info("构造请求体: {}", requestBody);
-
-            // 3. 构造请求URL
-            String url = String.format("%s?accessKey=%s&timestamp=%s&signature=%s",
-                    GET_USER_INFO_URL, dingTalkConfig.getAppId(), timestamp, signature);
-            logger.info("构造请求URL: {}", url);
-
-            // 4. 发送请求
-            logger.info("url===>"+url);
-            // 2. 将 String URL 转换为不编码的 URI
-            URI uri = new URI(url);  // 关键点:直接用URI构造函数,不额外编码
-            // 3. 发送请求(使用URI对象而非String URL)
-            ResponseEntity<String> response = restTemplate.postForEntity(
-                    uri,  // 传入URI对象而非String
-                    new HttpEntity<>(requestBody, buildHeaders()),
-                    String.class
-            );
-            logger.info("收到钉钉服务器响应,状态码: {}", response.getStatusCodeValue());
-            logger.info("完整响应: {}", response.getBody());
-
-            // 5. 解析响应
-            JsonNode jsonNode = parseResponse(response.getBody());
-            if (jsonNode == null) {
-                throw new RuntimeException("解析响应数据失败,返回的JSON为空");
-            }
-
-            JsonNode userInfo = jsonNode.get("user_info");
-            if (userInfo == null) {
-                logger.info("响应中缺少user_info字段,完整响应: {}", jsonNode.toString());
-                throw new RuntimeException("钉钉返回的用户信息不完整");
-            }
-
-            // 6. 获取用户详细信息
-            String unionId = userInfo.get("unionid").asText();
-            String openid = userInfo.get("openid").asText();
-
-            logger.info("成功获取用户信息 - unionId: {}, openid: {}", unionId, openid);
-            return openid;
+            String accessToken=getAccessToken(code);
+            // 2. 获取用户信息
+            Map<String, Object> userInfo = getUserInfo(accessToken,"me");
+            return userInfo.get("openId").toString();
 
         } catch (Exception e) {
             logger.info("获取用户OpenID失败,临时授权码: {},错误信息: {}", code, e.getMessage(), e);
             throw new RuntimeException("获取用户OpenID失败: " + e.getMessage(), e);
         }
     }
-    
+
     /**
-     * 获取用户详细信息
+     * 调用 /v1.0/contact/users/{unionId} 接口
      */
-    private DingTalkUserInfo getUserDetail(String unionId) {
-        // 1. 获取access_token
-        String accessToken = getAccessToken();
-        
-        // 2. 构造请求体
-        Map<String, Object> requestBody = new HashMap<>();
-        requestBody.put("unionid", unionId);
-        
-        // 3. 发送请求
-        ResponseEntity<String> response = restTemplate.postForEntity(
-                GET_USER_DETAIL_URL + "?access_token=" + accessToken,
-                new HttpEntity<>(requestBody, buildHeaders()),
-                String.class);
-        
-        // 4. 解析响应
-        JsonNode jsonNode = parseResponse(response.getBody());
-        JsonNode result = jsonNode.get("result");
-        
-        DingTalkUserInfo userInfo = new DingTalkUserInfo();
-        userInfo.setUnionId(unionId);
-        userInfo.setUserId(result.get("userid").asText());
-        userInfo.setName(result.get("name").asText());
-        userInfo.setAvatar(result.get("avatar").asText());
-        userInfo.setMobile(result.get("mobile").asText());
-        
-        return userInfo;
+    private Map<String, Object> getUserInfo(String accessToken, String unionId) {
+        String url = "https://api.dingtalk.com/v1.0/contact/users/" + unionId;
+
+        // 设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("x-acs-dingtalk-access-token", accessToken);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+
+        // 发送请求
+        ResponseEntity<Map> response = restTemplate.exchange(
+                url,
+                HttpMethod.GET,
+                new HttpEntity<>(headers),
+                Map.class
+        );
+
+        // 处理响应
+        if (!response.getStatusCode().is2xxSuccessful()) {
+            throw new RuntimeException("获取用户信息失败: " + response.getBody());
+        }
+
+        Map<String, Object> responseBody = response.getBody();
+        if (responseBody == null) {
+            throw new RuntimeException("无效的用户信息响应");
+        }
+        log.info("responseBody==>" + responseBody);
+
+        return responseBody;
     }
+
     
     /**
      * 获取access_token
      */
-    private String getAccessToken() {
-        String url = String.format(
-                "https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s",
-                dingTalkConfig.getAppId(), dingTalkConfig.getAppSecret());
-        
-        JsonNode jsonNode = parseResponse(restTemplate.getForObject(url, String.class));
-        return jsonNode.get("access_token").asText();
+    private String getAccessToken(String code) {
+        String url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken";
+        // 构建请求体
+        Map<String, String> requestBody = new HashMap<>();
+        requestBody.put("clientId", dingTalkConfig.getAppId());
+        requestBody.put("clientSecret", dingTalkConfig.getAppSecret());
+        requestBody.put("code", code);
+        requestBody.put("refreshToken", code);
+        requestBody.put("grantType", "authorization_code");
+
+        // 设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+
+        // 发送请求
+        ResponseEntity<Map> response = restTemplate.exchange(
+                url,
+                HttpMethod.POST,
+                new HttpEntity<>(requestBody, headers),
+                Map.class
+        );
+        // 处理响应
+        if (!response.getStatusCode().is2xxSuccessful()) {
+            throw new RuntimeException("获取access_token失败: " + response.getBody());
+        }
+
+        Map<String, Object> responseBody = response.getBody();
+        if (responseBody == null || !responseBody.containsKey("accessToken")) {
+            throw new RuntimeException("无效的响应数据");
+        }
+        log.info("responseBody==>: {}", responseBody);
+
+        return responseBody.get("accessToken").toString();
     }
     
     /**