1
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package cn.van333.wxsend.business.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.van333.wxsend.business.model.R;
|
||||
import cn.van333.wxsend.util.WeComCallbackCrypto;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/wecom/callback")
|
||||
public class WeComCallbackController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WeComCallbackController.class);
|
||||
|
||||
@Value("${qywx.app.corpId:}")
|
||||
private String corpId;
|
||||
|
||||
@Value("${qywx.app.token:}")
|
||||
private String token;
|
||||
|
||||
@Value("${qywx.app.encodingAESKey:}")
|
||||
private String encodingAESKey;
|
||||
|
||||
@GetMapping(produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String verify(@RequestParam("msg_signature") String msgSignature,
|
||||
@RequestParam("timestamp") String timestamp,
|
||||
@RequestParam("nonce") String nonce,
|
||||
@RequestParam("echostr") String echostr) {
|
||||
logger.info("WeCom callback verify: ts={}, nonce={}", timestamp, nonce);
|
||||
WeComCallbackCrypto crypto = new WeComCallbackCrypto(token, encodingAESKey, corpId);
|
||||
String plain = crypto.verifyURL(msgSignature, timestamp, nonce, echostr);
|
||||
return plain;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String receiveXml(@RequestParam("msg_signature") String msgSignature,
|
||||
@RequestParam("timestamp") String timestamp,
|
||||
@RequestParam("nonce") String nonce,
|
||||
HttpServletRequest request) throws IOException {
|
||||
String xml = readBody(request);
|
||||
logger.info("WeCom callback received xml: {}", xml);
|
||||
String encrypt = parseEncrypt(xml);
|
||||
WeComCallbackCrypto crypto = new WeComCallbackCrypto(token, encodingAESKey, corpId);
|
||||
String plainXml = crypto.decryptMsg(msgSignature, timestamp, nonce, encrypt);
|
||||
logger.info("WeCom callback plain xml: {}", plainXml);
|
||||
// TODO: 在此解析 plainXml 的 MsgType/Event/Content 等,进行业务处理
|
||||
return "success";
|
||||
}
|
||||
|
||||
private static String readBody(HttpServletRequest request) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try (BufferedReader reader = request.getReader()) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String parseEncrypt(String xml) {
|
||||
// 简单提取 <Encrypt><![CDATA[...]]></Encrypt>
|
||||
String start = "<Encrypt><![CDATA[";
|
||||
String end = "]]></Encrypt>";
|
||||
int i = xml.indexOf(start);
|
||||
int j = xml.indexOf(end);
|
||||
if (i >= 0 && j > i) {
|
||||
return xml.substring(i + start.length(), j);
|
||||
}
|
||||
// 兼容无 CDATA 的情况
|
||||
start = "<Encrypt>";
|
||||
end = "</Encrypt>";
|
||||
i = xml.indexOf(start);
|
||||
j = xml.indexOf(end);
|
||||
if (i >= 0 && j > i) {
|
||||
return xml.substring(i + start.length(), j);
|
||||
}
|
||||
throw new RuntimeException("Encrypt not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user