热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#开发微信门户及应用微信企业号的消息和事件的接收处理及解密

C#开发微信门户及应用微信企业号的消息和事件的接收处理及解密
1、企业号回调模式的设置

和公众号一样,微信企业号如果需要进行二次开发,也是需要在后台设置好对应的回调参数,如下界面所示。

设置好这些后,检查通过后,我们就可以在自己微信应用服务器上进行消息的收发操作了。

在回调的消息入口处,我们需要对POST数据和普通的GET数据进行分开处理,GET数据是微信自身的验证处理,POST数据是微信消息的交互操作。

    /// 
    /// 企业号回调信息接口。统一接收并处理信息的入口。    /// 
    public class corpapi : IHttpHandler
    {        /// 
        /// 处理企业号的信息        /// 
        /// 
        public void ProcessRequest(HttpContext context)
        {

上面我们定义了一个一般应用处理程序来对消息进行处理。

然后我们分开不同的消息类型(POST、GET 方式),针对性的进行处理。

                    if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
                    {                        using (Stream stream = HttpContext.Current.Request.InputStream)
                        {
                            Byte[] postBytes = new Byte[stream.Length];
                            stream.Read(postBytes, 0, (Int32)stream.Length);
                            postString = Encoding.UTF8.GetString(postBytes);
                        }                        if (!string.IsNullOrEmpty(postString))
                        {
                            Execute(postString, accountInfo);
                        }
                    }                    else
                    {
                        Auth(accountInfo);
                    }

2、微信回调消息的验证

下面是微信对于回调模式,验证URL的说明。

验证URL有效性

当你提交以上信息时,企业号将发送GET请求到填写的URL上,GET请求携带四个参数,企业在获取时需要做urldecode处理,否则会验证不成功。

参数描述是否必带
msg_signature微信加密签名,msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
timestamp时间戳
nonce随机数
echostr加密的随机字符串,以msg_encrypt格式提供。需要解密并返回echostr明文,解密后有random、msg_len、msg、$CorpID四个字段,其中msg即为echostr明文首次校验时必带

企业通过参数msg_signature对请求进行校验,如果确认此次GET请求来自企业号,那么企业应用对echostr参数解密并原样返回echostr明文(不能加引号),则接入验证生效,回调模式才能开启。

后续回调企业时都会在请求URL中带上以上参数(echostr除外),校验方式与首次验证URL一致。

根据上面的说明,我们需要获取这些参数,然后调用微信提供的消息处理函数进行加解密处理。

在验证URL的Auth(accountInfo);操作里面,我们可以看到核心的内容如下所示,就是获取到这些传递过来的参数信息,然后交给基类处理消息的签名内容。

                        #region 具体处理逻辑                        string echoString = HttpContext.Current.Request.QueryString["echoStr"];                        string signature = HttpContext.Current.Request.QueryString["msg_signature"];//企业号的 msg_signature
                        string timestamp = HttpContext.Current.Request.QueryString["timestamp"];                        string nOnce= HttpContext.Current.Request.QueryString["nonce"];                        string decryptEchoString = "";                        if (new CorpBasicApi().CheckSignature(token, signature, timestamp, nonce, corpId, encodingAESKey, echoString, ref decryptEchoString))
                        {                            if (!string.IsNullOrEmpty(decryptEchoString))
                            {
                                HttpContext.Current.Response.Write(decryptEchoString);
                                HttpContext.Current.Response.End();
                            }
                        } 
                        #endregion

验证代码部门如下所示。

        /// 
        /// 验证企业号签名        /// 
        /// 企业号配置的Token
        /// 签名内容
        /// 时间戳
        /// nonce参数
        /// 企业号ID标识
        /// 加密键
        /// 内容字符串
        /// 返回的字符串
        /// 
        public bool CheckSignature(string token, string signature, string timestamp, string nonce, string corpId, string encodingAESKey, string echostr, ref string retEchostr)
        {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, corpId);            int result = wxcpt.VerifyURL(signature, timestamp, nonce, echostr, ref retEchostr);            if (result != 0)
            {
                LogTextHelper.Error("ERR: VerifyURL fail, ret: " + result);                return false;
            }            return true;
        }

3、企业号的消息处理

上面介绍了,微信企业号对URL的验证过程,还有另外一个消息处理过程,就是微信服务器把消息发送给我们自己的应用服务器进行处理的过程,我们应用服务器需要在收到消息后,及时进行常规回复处理。

也就是下面的代码逻辑。

                    if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
                    {                        using (Stream stream = HttpContext.Current.Request.InputStream)
                        {
                            Byte[] postBytes = new Byte[stream.Length];
                            stream.Read(postBytes, 0, (Int32)stream.Length);
                            postString = Encoding.UTF8.GetString(postBytes);
                        }                        if (!string.IsNullOrEmpty(postString))
                        {
                            Execute(postString, accountInfo);
                        }
                    }

同样,我们给微信服务器回应消息的时候,我们也需要获得相应的参数,然后再行构造信息回答。

            string echoString = HttpContext.Current.Request.QueryString["echoStr"];            string signature = HttpContext.Current.Request.QueryString["msg_signature"];//企业号的 msg_signature
            string timestamp = HttpContext.Current.Request.QueryString["timestamp"];            string nOnce= HttpContext.Current.Request.QueryString["nonce"];

而另外一些参数信息,则是来源于我们企业号账号的配置参数。

            //获取配置参数并对加解密函数初始化
            string CorpToken = accountInfo.Token;            string AESKey = accountInfo.EncodingAESKey;            string CorpId = accountInfo.CorpID;

然后使用微信提供的消息加解密类,就可以顺利对消息进行加解密的处理了。具体操作代码如下所示。

            //根据参数信息,初始化微信对应的消息加密解密类
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(CorpToken, AESKey, CorpId);            //对收到的密文进行解析处理
            string sMsg = "";  // 解析之后的明文
            int flag = wxcpt.DecryptMsg(signature, timestamp, nonce, postStr, ref sMsg);            if (flag == 0)
            {                //LogTextHelper.Info("记录解密后的数据:");                //LogTextHelper.Info(sMsg);//记录解密后的数据
                CorpApiDispatch dispatch = new CorpApiDispatch();                string respOnseContent= dispatch.Execute(sMsg);                //加密后并发送                //LogTextHelper.Info(responseContent);
                string encryptRespOnse= "";
                timestamp = DateTime.Now.DateTimeToInt().ToString();
                wxcpt.EncryptMsg(responseContent, timestamp, nonce, ref encryptResponse, ref signature);

                HttpContext.Current.Response.COntentEncoding= Encoding.UTF8;
                HttpContext.Current.Response.Write(encryptResponse);
            }            else
            {
                LogTextHelper.Info("解密消息失败!");
            }

最终,我们把解密完成的消息交给对应的封装类进行统一处理就可以了。

                CorpApiDispatch dispatch = new CorpApiDispatch();                string respOnseContent= dispatch.Execute(sMsg);

这样我们在企业号API的封装,就可以只需要关注消息如何应答的逻辑就可以了,其他的不用关心。

更多C#开发微信门户及应用微信企业号的消息和事件的接收处理及解密相关文章请关注PHP中文网!

推荐阅读
  • [ToneTuneToolkit][022]
    #regionEnvironmentWindows1021H1Unity2020.3.30f1c1LTSVSCode1.67.2ToneTuneToolkit下载地址 https: ... [详细]
  • C语言是一个什么样的语言,为什么每个程序员都要学习
    对于大部分程序员,C语言是学习编程的第一门语言,很少有不了解C的程序员。C语言除了能让你了解编程的相关概念,带你走进编程的大门,还能让你明白程序的运行原理,比如,计算机的各个部件是 ... [详细]
  • mysql oneproxy稳定吗_Mysql 中间件 oneProxy总结
    建议使用之前把官方的文档全部通读一遍这里提供一个我的网盘地址oneproxy百度网盘0.先对oneproxy有个大概的了解,知道他所处的位置1.MySQL服务器创建t ... [详细]
  • 前言微服务架构(MicroserviceArchitecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。你可以将其看作是在架构层次而非获取服务 ... [详细]
  • npmimportuse这里我记录一下,视频地址和封面地址均引用的是服务器端得,本地的视频和图片 ... [详细]
  • webpack 配置IP 和端口号
    最近在用webpack搭建本地服务器的时候,因为不想总是用localhost来跑,所以对webpack.config.js进行了配置,如下devServer:{publicPath ... [详细]
  • Redis 外部访问设置
    1、错误原因Redis搭建好后一般都是使用编程语言进行连接调用,默认Redis的设置是不允许外界访问的,连接Redis只能通过本地(127.0.0.1)来连接,而不能使用网络IP( ... [详细]
  • 本文目录一览:1、学习Python之后可以做什么工作?有哪些方向? ... [详细]
  • c#中带getter和setter的接口类我在这里阅读http:msdn.microsoft.comen-uslibrary75e8y5dd%28vVS.100%29.aspx可以 ... [详细]
  • javascript演变史_Web方向思考,第1部分:JavaScript的演变和澳大利亚的入侵
    javascript演变史上个月,我很幸运地在略微阴沉的伦敦参加了WebDirectionsmedia。这次活动吸引了网络世界中所有的推动者和推动者,这 ... [详细]
  • 缓冲区溢出实例(一)–Windows
    一、基本概念缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获 ... [详细]
  • 102安装Linux系统
    安装Linux系统 安装CentOS系统准备系统光盘插入CentOS7光盘,引导安装程序设置主机,将光盘作为第一-引导设备从CentOS7光盘启动主机检测安装光盘的完整性从ISO镜 ... [详细]
  • docker整体了解
    Docker是一个基于LXC技术构建的容器引擎,基于Go语言开发,遵循Apache2.0协议开源Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移 ... [详细]
  • C#使用System.Net.Mail类实现邮件发送【.Net开发】
    这篇文章介绍了C#使用System.Net.Mail类实现邮件发送的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值, ... [详细]
  • Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理,现在在企业中的使用率也是很广的。git是一个分布式的版本控制系统,不像以前的svn,svn是 ... [详细]
author-avatar
书友67997456_296
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有