Selaa lähdekoodia

新增微信接口校验

hsj 1 kuukausi sitten
vanhempi
commit
b31a7778de

+ 1 - 1
src/main/java/top/husj/husj_wx/config/AccessTokenConfig.java

@@ -31,7 +31,7 @@ public class AccessTokenConfig {
             if (jsonResponse.containsKey("access_token")) {
                 String accessToken = jsonResponse.getString("access_token");
                 AccessTokenUtil.setAccessToken(accessToken);
-                log.info("成功获取access_token: {}", accessToken.substring(0, 10) + "...");
+                log.info("成功获取access_token: {}", accessToken);
             } else {
                 String errorMsg = jsonResponse.getString("errmsg");
                 log.error("获取access_token失败: {}", errorMsg);

+ 21 - 5
src/main/java/top/husj/husj_wx/controller/WeChatController.java

@@ -1,27 +1,43 @@
 package top.husj.husj_wx.controller;
 
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 import top.husj.husj_wx.entity.model.WeChatMsg;
+import top.husj.husj_wx.utils.WeChatSignatureUtil;
 
 @RestController
 @RequestMapping("/wechat")
+@Slf4j
 public class WeChatController {
 
     private final String TOKEN = "你设置的Token";
 
     // 1. 微信后台验证 URL 时使用 (GET)
     @GetMapping("/callback")
-    public String checkSignature(String signature, String timestamp, String nonce, String echostr) {
-        // 这里需要按照微信算法:将token、timestamp、nonce字典排序并SHA1加密,对比signature
-        // 为了演示快速上手,这里直接返回 echostr(正式环境必须校验!)
-        return echostr;
+    public String checkSignature(
+            @RequestParam("signature") String signature,
+            @RequestParam("timestamp") String timestamp,
+            @RequestParam("nonce") String nonce,
+            @RequestParam("echostr") String echostr) {
+
+        log.info("收到微信服务器验证请求 - signature: {}, timestamp: {}, nonce: {}",
+                signature, timestamp, nonce);
+
+        // 校验签名
+        if (WeChatSignatureUtil.checkSignature(signature, timestamp, nonce)) {
+            log.info("微信服务器验证成功");
+            return "true";
+        } else {
+            log.error("微信服务器验证失败 - 签名不匹配");
+            return "error";
+        }
     }
 
     // 2. 接收用户消息 (POST)
     @PostMapping(value = "/callback", consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE)
     public String handleMessage(@RequestBody WeChatMsg msg) {
-        System.out.println("收到来自用户 " + msg.getFromUserName() + " 的消息:" + msg.getContent());
+        log.info("收到来自用户 {} 的消息:{}", msg.getFromUserName(), msg.getContent());
 
         // 构造被动回复(同样是XML)
         return String.format(

+ 65 - 0
src/main/java/top/husj/husj_wx/utils/WeChatSignatureUtil.java

@@ -0,0 +1,65 @@
+package top.husj.husj_wx.utils;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+/**
+ * 微信签名校验工具类
+ */
+public class WeChatSignatureUtil {
+    
+    // 这里的token需要与微信公众平台配置的Token保持一致
+    private static final String TOKEN = "YourTokenHere";
+    
+    /**
+     * 校验微信签名
+     * @param signature 微信请求签名
+     * @param timestamp 时间戳
+     * @param nonce 随机数
+     * @return 校验结果
+     */
+    public static boolean checkSignature(String signature, String timestamp, String nonce) {
+        // 1. 将token、timestamp、nonce三个参数进行字典序排序
+        String[] arr = new String[]{TOKEN, timestamp, nonce};
+        Arrays.sort(arr);
+        
+        // 2. 将三个参数字符串拼接成一个字符串
+        StringBuilder content = new StringBuilder();
+        for (String s : arr) {
+            content.append(s);
+        }
+        
+        // 3. 进行sha1加密
+        String temp = getSha1(content.toString());
+        
+        // 4. 与signature对比,标识该请求来源于微信
+        return temp != null && temp.equals(signature);
+    }
+    
+    /**
+     * SHA1加密方法
+     */
+    private static String getSha1(String str) {
+        if (str == null || str.length() == 0) {
+            return null;
+        }
+        
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            byte[] digest = md.digest(str.getBytes("UTF-8"));
+            
+            // 将字节数组转换为十六进制字符串
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : digest) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) {
+                    hexString.append('0');
+                }
+                hexString.append(hex);
+            }
+            return hexString.toString();
+        } catch (Exception e) {
+            throw new RuntimeException("SHA1加密失败", e);
+        }
+    }
+}