关于.NetCore中第三方开放平台接受微信推送的授权消息以及事件消息

如何处理微信开放平台中微信推送的消息


为什么还要写微信消息接收的文章

          最近项目由.net framework框架升级到了Core

          客户有新的需求,需要统计公众号取消关注人数以及新增粉丝数,需要用到事件消息接收

          上一篇文章写的不够详细,依然有很多人问我,应该怎么处理微信授权消息

复习要点

  1. 如何在Core2.0中处理授权事件接收消息
  2. 如何在Core2.0中处理消息与事件接收消息      

正文


为什么我们需要处理微信推送的消息

  1. 授权事件接受的消息,主要用于获取或者刷新授权公众号的授权信息,主要是AccessToken
  2. 消息与事件接受的消息,有两部分作用:
  • 申请微信开放平台时,权限选择部分,在公众号权限中,如果选择了消息管理权限,即:帮助公众号接收用户消息,进行人工客服回复或自动回复。那么所有用户消息将会推送至该Url
  • 用户事件消息,即用户行为消息,也会推送至该Url,如,关注公众号,取消关注公众号,核销卡劵,删除卡劵等

我们如何处理微信推送消息

    开发资料填写


  1. 申请微信开放平台,在填写开发资料步骤,我们需要填写如下内容:
  • 授权发起页域名。建议填写顶级域名,如:www.xxxx.com/www.xxxx.cn;针对这个域名的解释很清晰:必须从本域名内网页跳转到登录授权页,才可完成登录授权。无需填写http://等域名协议前缀。必须从本域名内网页跳转至登录授权页。也就是说,公众号授权必须从该域名发起或者该域名的子域名发起。为了更灵活的配置开放平台的发起域名信息,我建议在这里填写顶级域名。毕竟我们的顶级域名只有一个,二级域名可以随意创建。
  • 授权测试公众号列表。我们可以随意填写一个本公司用于测试的微信公众号的原始ID,请注意,是原始ID,并非AppId。在开放平台未发布成功之前,我们可以使用该测试公众号测试我们的代码是否正确无漏洞。
  • 授权事件接收URL。这个地址,是我们这篇文章介绍的重点之一。微信的解释如下:用于接收取消授权通知、授权成功通知、授权更新通知,也用于接收ticket,ticket是验证平台方的重要凭据。
  • 消息校验Token。我们接受到的所有消息,事件消息,用户消息,以及授权通知消息,ticket消息等,我们都需要使用该Token校验消息的合法性。
  • 消息加解密Key。微信推送给开放平台的所有消息都经过了加密处理,我们需要使用该Key,对消息进行解密,获取消息体内容。
  • 消息与事件接收URL。这个地址,也是我们这篇文章介绍的重点之一,微信的解释如下:通过该URL接收公众号或小程序消息和事件推送,该参数按规则填写(需包含/$APPID$,如www.abc.com/$APPID$/callback),实际接收消息时$APPID$将被替换为公众号或小程序AppId。这个地址在填写时,必须包含/$APPID$,如:https://www.xxxx.com/Receive/EventMessage/$APPID$
  • 公众号开发域名。同样建议填写顶级域名,毕竟我们的开放平台部署完成之后,我们需要代公众号实现业务,代公众号做H5小游戏与粉丝互动,当我们需要粉丝分享至朋友圈或者需获取粉丝位置信息时,我们需要调用微信JS接口。注意:使用开放平台获取的公众号Acctoken,做微信Js接口数字签名时,做签名的页面的Url地址必须与公众号开发域名一致,或为该开发域名的二级域名。所以,在这里,我同样建议填写顶级域名。

    授权事件接收URL


    首先这个地址所属域名必须与授权发起页域名保持一致,如:授权发起页域名为:www.xxxx.com。那我们的授权事件接收Url      则为https://www.xxxx.com/Receive/SysMessage

    在这个Url中,我们将会接受两种类型的消息。授权通知消息跟ticket消息。

  • 在全网发布之前,我们只会接受到ticket消息。该ticket消息很重要,是我们获取授权公众号Acctoken的主要凭据。
  • 在全网发布之后,我们还会接受到微信公众号的授权通知,取消授权通知以及更新授权通知。

    消息接收

     我们先通过日志,分析一下微信是怎么请求我们这个接口的,通过日志我们发现;微信实际请求的地址为:

 http://www.xxxx.com/Receive/SysMessage?signature=692ded0848127c81dc46da67bb7cb14925we51ee&timestamp=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>
  1. 通过分析,我们得到如下结论:
  • 微信请求授权事件Url时,带了五个参数,分别为:Signature,Timestamp,Nonce,Encrypt_type,Msg_Signature
  • 同时还Post了一段需要解密的Xml流文件。

      为避免第一次接触Core2.0的同学踩到跟我一样的坑,我分享一下怎么接收流文件以及参数。

     参数部分,我们正常接收即可,流文件,用 Request.GetRequestMemoryStream()正常接收即可。关于参与部分,我们可以         封装成一个实体对象接收,也可以单个参数接受。

     接收流文件一定要注意,在Core中,流文件仅允许读取一次,故,我第一次接收到流文件之后,读取并打印出来之后,导致         后边的程序一直无法读取流文件,程序一直报错,后来才了解到这个机制。我们想要重复接收流文件怎么办?

  • 第一,我们可以将这段流文件先读取出来,存储在内存中,或者直接转换为XMLDocument对象,存储下来。
  • 第二,我们可以在读取流文件之前,加入如下代码
HttpContext.Request.EnableRewind();
HttpContext.Request.Body.Position = 0;
HttpContext.Request.Body.Seek(0, 0);

   消息处理

   我们需要对接收到的消息,进行解密处理,并获取到ticket,这个才是我们的最终目的。

   我们在解密之前,有两件事情需要处理

  • 部署缓存数据服务(Redise或者Memcached)
  • 在开放平台的资源中心下载微信提供的SDK

      我们通过分析微信提供给我们的SDK,得知,解密XML文件我们需要初始化对象WXBizMsgCrypt。该类包含一个三个参数的构  造函数,参数分别为:Token,EncodingAESKey,AppId。这三个参数微信在推送消息时,均提供给了我们。直接拿来使用即可。

       同时,在WXBizMsgCrypt对象中,提供了DecryptMsg方法,用于校验消息的合法性并返回解密结果。该方法包含5个参数,分别为sMsgSignature,sTimeStamp,sNonce,sPostData,返回sMsg。

参数名称参数描述来源
Msg_Signature签名推送消息接收的参数
Timestamp时间戳推送消息接收的参数
Nonce随机数推送消息接收的参数
postDataStr流文件XmlXML文件直接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&timestamp=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>

通过分析,我们得到如下结论:

  • 微信请求授权事件Url时,同样带了五个参数,分别为:Signature,Timestamp,Openid,Encrypt_type,Msg_Signature,应该还有一个微信公众号的AppId,在请求的Url中
  • 同时还Post了一段需要解密的Xml流文件。

同样我们需要解密该Xml文件,解密方式同授权通知推送消息解密。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值