微信公众号第三方授权开发——推送component_verify_ticket协议

微信公众号第三方授权——接受微信推送component_verify_ticket协议




作者:凌晨四点的newyork



接收component_verify_ticket

在第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket。第三方平台方在收到ticket推送后也需进行解密(详细请见【消息加解密接入指引】),接收到后必须直接返回字符串success。

一、接受到微信推送的消息参数值如下

/**
	 * @title 微信端定时通知ticket接收
	 * @param timestamp
	 * @param nonce
	 * @param msgSignature
	 * @return
	 */
	@RequestMapping(value = "/ticket", produces = "application/json; charset=utf-8")
	public String notifyWxTicket(@RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce,
			@RequestParam("msg_signature") String msgSignature, @RequestBody String postData)

参数说明:timestamp时间戳;nonce随机字符串;msg_signature签名串;postData即xml数据内容。
postData数据示例:

<xml>
	<AppId><![CDATA[AppId]]></AppId>
	<Encrypt><![CDATA[加密XML]]></Encrypt>
</xml>

二、解密xml数据内容
下载官方demo

找到java的文件夹
在这里插入图片描述
在项目中的pom文件,添加如下依赖:

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
	<groupId>commons-codec</groupId>
	<artifactId>commons-codec</artifactId>
	<version>1.9</version>
</dependency>
<!--解密jar包-->
<dependency>
	<groupId>com.aes</groupId>
	<artifactId>aes-jre</artifactId>
	<version>1.6</version>
</dependency>

注意:此处引入微信第三方的jar包需要使用maven引入本地jar包。

使用微信第三方的jar包提供的方法对xml数据解密
将参数换成上面接受到的参数数据

/**
	 * 对微信推送消息进行解密,获取ComponentVerifyTicket
	 * 
	 * @param timestamp
	 * @param nonce
	 * @param msgSignature
	 * @param postData
	 * @return
	 */
	public Map<String, String> Decrypt(String timestamp, String nonce, String msgSignature, String postData)
			throws Exception {
		log.info("token: " + token);
		log.info("encodingAesKey: " + encodingAesKey);
		log.info("appId: " + appId);
		WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
		String requestXml = pc.decryptMsg(msgSignature, timestamp, nonce, postData);
		log.info("解密后明文是: " + requestXml);
		Map<String, String> xmlMap = XMLParser.getMapFromXML(requestXml);//xml格式数据转map
		return xmlMap;
	}

高能预警,如下内容,皆为真实亲测,微信第三方jar包中存在一部分坑…
下面是jar包中的源码,对于上面提到的密文postData的提取代码:(箭头表示------点进去)
在这里插入图片描述在这里插入图片描述

/**
	 * 提取出xml数据包中的加密消息
	 * @param xmltext 待提取的xml字符串
	 * @return 提取出的加密消息字符串
	 * @throws AesException 
	 */
	public static Object[] extract(String xmltext) throws AesException     {
		Object[] result = new Object[3];
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			StringReader sr = new StringReader(xmltext);
			InputSource is = new InputSource(sr);
			Document document = db.parse(is);

			Element root = document.getDocumentElement();
			NodeList nodelist1 = root.getElementsByTagName("Encrypt");
			NodeList nodelist2 = root.getElementsByTagName("ToUserName");
			result[0] = 0;
			result[1] = nodelist1.item(0).getTextContent();
			result[2] = nodelist2.item(0).getTextContent();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			throw new AesException(AesException.ParseXmlError);
		}
	}

注意看这五行代码

			NodeList nodelist1 = root.getElementsByTagName("Encrypt");
			NodeList nodelist2 = root.getElementsByTagName("ToUserName");
			result[0] = 0;
			result[1] = nodelist1.item(0).getTextContent();
			result[2] = nodelist2.item(0).getTextContent();

与上面贴出的postData数据示例做比对,发现微信推送过来的xml数据包中并没有ToUserName这个标签。说明一下,这个ToUserName实际上是一个微信号,在此处微信并没有推送,所以只需把上边这五行代码中跟ToUserName有关的代码去掉即可,与此同时,需要去掉如下图中的两个异常,否则会一直发生异常。
在这里插入图片描述
贴一个我解密后的数据示例:

<xml>
<AppId><![CDATA[wx6***********26]]></AppId>
<CreateTime>1557371567</CreateTime>
<InfoType><![CDATA[component_verify_ticket]]></InfoType>
<ComponentVerifyTicket><![CDATA[ticket@@@*******************]]></ComponentVerifyTicket>
</xml>

需要提取出ComponentVerifyTicket这个的值,ComponentVerifyTicket的有效时间为12小时,建议保存最近可用的component_verify_ticket,提供后续获取第三方component_access_token时使用,保存方式自选,可以是数据库,缓存,或静态类等。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值