第三方平台审核通过后,微信服务器会每10分钟向创建第三方平台时填写的授权事件接收URL推送一次component_verify_ticket,
用于获取第三方平台接口调用凭据。
/**
* 接收微信服务器的推送
* @param request
* @param response
* @throws AesException
* @throws IOException
*/
@RequestMapping(value = "/event/authorize")
public void acceptAuthorizeEvent(HttpServletRequest request, HttpServletResponse response)
throws AesException, IOException {
processAuthorizeEvent(request);
output(response, "success");
}
/**
* 处理授权事件的推送
* @param request
* @throws AesException
* @throws IOException
*/
public void processAuthorizeEvent(HttpServletRequest request)
throws AesException, IOException {
String postStr = request.toString();
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
String signature = request.getParameter("signature");
String msgSignature = request.getParameter("msg_signature");
logger.info("noce:{},timestamp:{}", nonce, timestamp);
logger.info("signature:{},msgSignature:{}", signature, msgSignature);
if (!StringUtils.isNotBlank(msgSignature))
return;
StringBuilder sb = new StringBuilder();
BufferedReader in = request.getReader();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
String xml = sb.toString();
logger.info("解密前:{}", xml);
WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(Constants.COMPONENT_TOKEN, Constants.COMPONENT_ENCODINGAESKEY, Constants.COMPONENT_APPID);
xml = wxBizMsgCrypt.decryptMsgTwo(msgSignature, timestamp, nonce, xml);
logger.info("解密后:{}", xml);
openWxService.saveTicketToRedis(xml);
}
接收到的xml格式
<xml>
<AppId><![CDATA[????]]></AppId>
<Encrypt><![CDATA[/m5pK5R6r4EBy3vPwpaTdGo7/u2Niv/qxu+yrZJjQiUuxVdRQfgRI3STSrSxrdf53NRfhd1gE8N7hItgiN67oJc+viXhXZEC7YZzlyAUkTQ68g6TrKiPdwiNNMHNWPSqYbkOBTtRJ2UBVCNmHf1H1rwX8b3qnRHI4buPoVn7qKJcNoI4SnFiH9HU6HTbCtBhfD1fgar0o7PKZDFksFrAC6IjwMs1/nm7Ow6JiGAqnNfJVWN21/GDQ2DWcZTK5GuVPg+yM6c7HpjWq12D4p7ItSFAAZefalYQF1blwfRFRx9ZB68BSMLYjjbENx5nuzAZsxHm9g7J4D6oJjw+mOq4IcHSYc5ukx8FDxitsy2cAcpqnYoVHfVLvCFoSa0blC/zsplhpc88mXMbZ8oDl/+gUBNEUVVqXfWsA6d6sZFLifHOR8kN7NUaX+RhL0nLX8VkrX0fowFqMy6Xn3FPJHeAWw==]]></Encrypt>
</xml>
接收到微信服务器推送的ticket进行处理后,必须直接返回success。
这里微信服务器推送过来的ticket信息是加密的,所以我们接收时需要进行解密,解密我用的是微信开放平台API文档提供的加密解密方式,
这里提供[下载地址](http://mp.weixin.qq.com/wiki/static/assets/a5a22f38cb60228cb32ab61d9e4c414b.zip)。里面提供的解密方式只是对于ToUserName的解密方式,
我们需要加个AppId的解密方式。
/**
* 缓存Ticket
* @param xml
*/
@Override
public void saveTicketToRedis(String xml) {
Document document;
try {
document = DocumentHelper.parseText(xml);
Element element = document.getRootElement();
String ticket = element.elementText("ComponentVerifyTicket");
if (StringUtils.isNotEmpty(ticket)) {
logger.info("缓存component_verify_ticket协议{}", ticket);
redisWrite.set(OpenWxEnum.COMPONENT_VERIFY_TICKET.getCode(), ticket);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
缓存ticket我这里用的是redis缓存,大家可以用自己熟悉的缓存方式进行ticket的缓存。