技术标签: 微信开放平台
为什么还要写微信消息接收的文章
最近项目由.net framework框架升级到了Core
客户有新的需求,需要统计公众号取消关注人数以及新增粉丝数,需要用到事件消息接收
上一篇文章写的不够详细,依然有很多人问我,应该怎么处理微信授权消息
复习要点
为什么我们需要处理微信推送的消息
我们如何处理微信推送消息
开发资料填写
授权事件接收URL
首先这个地址所属域名必须与授权发起页域名保持一致,如:授权发起页域名为:www.xxxx.com。那我们的授权事件接收Url 则为https://www.xxxx.com/Receive/SysMessage
在这个Url中,我们将会接受两种类型的消息。授权通知消息跟ticket消息。
消息接收
我们先通过日志,分析一下微信是怎么请求我们这个接口的,通过日志我们发现;微信实际请求的地址为:
http://www.xxxx.com/Receive/SysMessage?signature=692ded0848127c81dc46da67bb7cb14925we51ee×tamp=1568969944&nonce=1382428071&encrypt_type=aes&msg_signature=f6ee103a5c0189444778bfe9c19e13ewe44790ed
同时,还推送给我们一段文件流信息,信息内容如下:
<xml>
<AppId><![CDATA[wx1ab295c5c21ab302]]></AppId>
<Encrypt><![CDATA[sZax/4ZVbkyt2ukHDGDTg5G5p7LSn2VyycjYcXngIWElTr0suFA41SyAeNNwAy/UNmk9cUjzmYFlYrDf3zM7YObDgxP9zJBa1Y9yIWb6iluKBr3rc2P5/NQwhyESSpNPf/HgyQ3jNxMPnzAMxyGkwD3e3L0cjLQLN2PT8ICHKB8lHddJzdQJdxsTZ+Ihxkip6KSMmkT5li4DlY/eBmBwaG2nLZCM6NGFPhYVe0TDOS5i8yohyeD5Vs48i5gDmUe5EqPNvG6bJi1xUlikVLxIFZJGJkGHOurRjM8avK4mj8z3R3kKO312122/svkaBM6sQYjYf79lxNNuU6/IPByWt6Vtrf5rp2N0ccnaXmVp4lxrjkaUBrLJ2DkLxwblsWHRu/taE2wyRBUr121ohGJEBO2itsY4Qk/MZ6Sbi+qjKA6irUQedwnBy0ajPZx9GbWGILWL8sQkFNm6K9AnPJdeViw==]]></Encrypt>
</xml>
为避免第一次接触Core2.0的同学踩到跟我一样的坑,我分享一下怎么接收流文件以及参数。
参数部分,我们正常接收即可,流文件,用 Request.GetRequestMemoryStream()正常接收即可。关于参与部分,我们可以 封装成一个实体对象接收,也可以单个参数接受。
接收流文件一定要注意,在Core中,流文件仅允许读取一次,故,我第一次接收到流文件之后,读取并打印出来之后,导致 后边的程序一直无法读取流文件,程序一直报错,后来才了解到这个机制。我们想要重复接收流文件怎么办?
HttpContext.Request.EnableRewind();
HttpContext.Request.Body.Position = 0;
HttpContext.Request.Body.Seek(0, 0);
消息处理
我们需要对接收到的消息,进行解密处理,并获取到ticket,这个才是我们的最终目的。
我们在解密之前,有两件事情需要处理
我们通过分析微信提供给我们的SDK,得知,解密XML文件我们需要初始化对象WXBizMsgCrypt。该类包含一个三个参数的构 造函数,参数分别为:Token,EncodingAESKey,AppId。这三个参数微信在推送消息时,均提供给了我们。直接拿来使用即可。
同时,在WXBizMsgCrypt对象中,提供了DecryptMsg方法,用于校验消息的合法性并返回解密结果。该方法包含5个参数,分别为sMsgSignature,sTimeStamp,sNonce,sPostData,返回sMsg。
参数名称 | 参数描述 | 来源 |
---|---|---|
Msg_Signature | 签名 | 推送消息接收的参数 |
Timestamp | 时间戳 | 推送消息接收的参数 |
Nonce | 随机数 | 推送消息接收的参数 |
postDataStr | 流文件Xml | XML文件直接ToString()即可 |
直接调用,返回的sMsg即为我们最终想要的结果:
四种授权通知消息,解密后的结果不同,我就不一一列举了。这个节点还算清晰。
<?xml version="1.0" encoding="utf-8"?>
<xml>
<AppId><![CDATA[wx1ab295c5cc7ab302]]></AppId>
<CreateTime>1569168398</CreateTime>
<InfoType><![CDATA[component_verify_ticket]]></InfoType>
<ComponentVerifyTicket><![CDATA[ticket@@@PVIT0tApDDwt8UkCwqeF1O9ZongIK-y0pltF-WNO9OOT5eyewYOQoWg8hvU5vP2b9_YN9velMRqzSxr10trcMA]]></ComponentVerifyTicket>
</xml>
我们主要通过InfoType来区分,消息类型。这里我着重说明一下component_verify_ticket消息。
我的处理方式是,当接受到component_verify_ticket消息之后,我会将ticket消息写入文本文件。并根据推送消息不停覆盖该文本。因为ticket可是我们管理公众号的重要凭据。
如果有公众号开发经验的话,我们都知道,获取有关公众号的所有信息,我们都需要用到acctoke这个票据。而ticket是我们使用开放平台换取acctoken的重要凭据。那我们应该怎么通过ticke换取Token留在开放平台管理公众号文章中再详细说明,本文仅介绍如何处理微信推送的授权消息。
至此,我们的授权事件接收就算处理完了。
消息与事件接收URL
同样,这个地址所属域名必须与授权发起页域名保持一致,如:授权发起页域名为:www.xxxx.com。那我们的消息与事件接收Url 则为https://www.xxxx.com/Receive/EventMessage
在这个Url中,同样,我们也会接受两种类型的消息。
消息接收
同样,我们先分析日志,分析一下微信是怎么请求我们这个接口的,通过日志我们发现;微信实际请求的地址为:
http://www.xxxx.com/Receive/EventMessage/wxf50cbe181c823526?signature=afab092b6ed320aaadb5e84025e868bbbf86b78b×tamp=1569109822&nonce=1958085416&openid=oAvaB1N8afpZuAh5D7IgTGn9Zdlc&encrypt_type=aes&msg_signature=836e160d6921243851e5c121d7bc83aa3fde67ea
同授权消息不同的是,微信直接请求的地址后,带了公众号的AppId,故,请一定要配置好我们的路由规则。
同时,还推送给我们一段文件流信息,信息内容如下:
<xml>
<AppId><![CDATA[wx1ab295c5cc7ab302]]></AppId>
<Encrypt><![CDATA[xbG1dATam7xUScgz4bzSJRWeJgeS0mPwBFAW9F+0wJaKIkKoVjq0NItzl7MztokiuYpoNSRdiRXuQUivFTB3yZG36hgBcBPN8wPTbdOH+Xfb70fJdw8CQDuYqY8fqyRREMBpeFujzQvprnVUM0S/bar/RSwl8Uzu/kHfUnvTEOK6rjvQgJmJ1sZr+JoLcw4SC5+W42ByHNKkIrZWckV/Z5sSQeDQJwAPG4+ir6+IHU24B6+b/9JtSC5TpeF0tfgljMyOkY6OVmolqjlnWno9M2ppEEIgxsx5CKjcb7MMgqIAD4ptiwjDuH9O3p23ZvYogjxVNUpKfcuXS2abS6fS2q8YjbDYRyIn8gj5YnWUVy3784zBH1hJqdUNzlFylasn34oCwmBFuLNM44Ipux6fN61H1ZeJF3FMbEkm/rGKp5/IfVrO0xrlha6xFvGJjhs9qAuWhe5bhhrceb8U/jfUPw==]]></Encrypt>
</xml>
通过分析,我们得到如下结论:
同样我们需要解密该Xml文件,解密方式同授权通知推送消息解密。
文章浏览阅读3.8k次。在java中,static关键字代表的含义为"静态的",只要在方法或者属性前面加上了static关键字,这个方法或属性就属于类了,如果没有static关键字,方法或属性是属于这个类的对象。我们称加上static关键字的属性和方法为静态属性和静态方法,不加static关键字的属性和方法我们称为为普通属性和普通方法。普通属性和普通方法可以随着对象的多次创建而被重复使用,而静态属性和静态变量是唯一的,只..._静态内部类中的静态属性可以直接访问吗
文章浏览阅读4.6k次,点赞11次,收藏28次。前言: echarts实现西安地铁图效果图:官网入口实现代码:var data = [ { name: "地铁一号线", tooltip: { formatter: "{b}: 19999<br />" }, symbolSize: 0.1, value: [5, 750], x: 800, ..._echarts地铁图
文章浏览阅读155次。类型 速率 距离 标准 编码 工作模式 10BASE-T UTP 10Mbps 100m IEEE802.3i 10BASE-2 200m 10BASE-5 500m 100Base-TX UTP-5类或匹配电阻为150Ω的STP 100Mbps 100M IEEE802.3 4B/5B曼_等比例压缩传输和变比例传输的区别
文章浏览阅读307次。这里写自定义目录标题页面设计全局三个文件Pages 目录文件创建页面把内容单元封装在view内部插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入页面设计全局三个文件分别是app.jsapp.jsonapp.wxss名称不可更改Pages 目录文件用来放各个页面的标_进公司第一天写微信小程序的项目
文章浏览阅读1.4k次。(只有气到我肺都炸了的情况下我才可能废一些时间去写博客(主要是写一些气话),但现在气消得差不多了我也骂不出什么话了。正文1、字符串拼接分软拼接和硬拼接(“软硬拼接”是我自己发明的词~实际上到底有没有这种说法我就没去管了)2、所谓软拼接,就是字符串后面加的是【字符串】;硬拼接就字符串后面加的是【字符】 3、软拼接,只会拼接'\0'之前的有效字符;硬拼接,是什么字符都能硬加进去,包括'\0'4、硬拼接如果拼接的是'\0',在判等的时候很大概率翻车。(在map的find函数里会要用到判等的。没错我就这翻_c++字符串拼接缺失
文章浏览阅读86次。当服务器遇到性能瓶颈需要进行扩展时,一般来说有两种解决思路:Scale-up 和 Scale out,也称作垂直扩展和水平扩展。常见的负载均衡器根据工作在的协议层划分可划分为:四层负载均衡:根据请求报文中的目标地址和端口进行调度七层负载均衡:根据请求报文的内容进行调度,这种调度属于「代理」的方式根据软硬件划分:硬件负载均衡:F5 的 BIG-IPCitrix 的 NetSca...
文章浏览阅读339次。链表二叉树链接如下sdut oj 数据结构实验之二叉树五:层序遍历 (链表).数组模拟方式见下文Description已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示空结点)。请建立二叉树并求二叉树的层次遍历序列。Input输入数据有多行,第一行是一个整数t (t<1000),代表有t行测试数据。每行是一个长度小于50个字符的字符串。Output输出二叉树的层次遍历序列。SampleInput2abd,,eg,,,cf,,,xnl,,i,,u,,Outpu_数组模拟树的层次遍历
文章浏览阅读598次。ListView分页加载数据ListView分页加载 在Android中是一个经常用到的技术,当我们需要加载大量的数据到列表显示时,假如一次性把所有数据加载完毕,可能会导致整个ListView列表卡顿,给用户的体验也非常不好。因而,我们可以将数据分为多次加载,每次加载其中的一部分,用户有需求的时候再加载其他部分,这样的设计会更加友好。 ListView分页原理在日常开发中,我们可能会遇到以下两种情_listview按页请求数据
文章浏览阅读1.5w次,点赞5次,收藏37次。1.通过请求获取权限,放入localStorage:(这里是多个权限,保存为字符串,用逗号隔开)window.localStorage.setItem("permissionPage", "editPage,detailPage");window.localStorage.setItem("permissionButton", "canEdit,canDelete");2.在main.ts中引入:import hasPermission from '@/common/utils/hasPermi_v-has
文章浏览阅读6.8k次,点赞8次,收藏23次。分析乘法表发现,整体有九行,第一行是一列,第二行是两列,第三行三列.....第九行对应有九列,所以它的行数对应就有多少列,这样我们可以通过借助行数来控制它的列数,以此来实现乘法表的打印。具体代码实现:for循环public class MultTable { public static void main(String[] args) { //此处调用九九乘法表方法实现打印 multMethod(); } public static void multMethod() { /_java用循环和分支结构写九九乘法表
文章浏览阅读6.1k次。运算符概述1) 算术运算符执行算术运算,例如:加、减、乘、除等。2) 比较运算符包括大于、小于、等于或不等于、等等。主要用于数值的比较、字符串的匹配等方面。3) 逻辑运算符包括与、或、非和异或、等逻辑运算符。其返回值为布尔型,真值(1 或 true)和假值(0 或 false)。4) 位运算符包括按位与、按位或、按位取反、按位异或、按位左移和按位右移等位运算符。位运算必须先将数据转换为补码,然后在根据数据的补码进行操作。运算完成后,将得到的值转换为原来的类型(十进制数),返回_数据库运算符
文章浏览阅读87次。龙芯软件开发(24)-- PCI设备初始化2 ..._龙芯pci中断绑定