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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

在上篇随笔《C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)》介绍了有关企业号的消息发送,官方特别声明消息是不用加密发送的。但是在回调的服务器上,也就是我们网站的服务器上,微信传过来的消息是加密的,需要我们调用类库对消息和事件进行解密操作,由于官方的例子不全,因此摸索了不少时间,最终顺利解密收到的各种消息和事件。本文主要介绍 微信企业号的消息和事件的接收处理及解密操作。

1、企业号回调模式的设置

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

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

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

    /// <summary>
    /// 企业号回调信息接口。统一接收并处理信息的入口。
    /// </summary>
    public class corpapi : IHttpHandler
    {
        /// <summary>
        /// 处理企业号的信息
        /// </summary>
        /// <param name="context"></param>
        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

验证代码部门如下所示。

        /// <summary>
        /// 验证企业号签名
        /// </summary>
        /// <param name="token">企业号配置的Token</param>
        /// <param name="signature">签名内容</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonce">nonce参数</param>
        /// <param name="corpId">企业号ID标识</param>
        /// <param name="encodingAESKey">加密键</param>
        /// <param name="echostr">内容字符串</param>
        /// <param name="retEchostr">返回的字符串</param>
        /// <returns></returns>
        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#开发微信门户及应用》系列感兴趣,可以关注我的其他文章,系列随笔如下所示:

C#开发微信门户及应用(25)-微信企业号的客户端管理功能

C#开发微信门户及应用(24)-微信小店货架信息管理

C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试

C#开发微信门户及应用(22)-微信小店的开发和使用

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

C#开发微信门户及应用(20)-微信企业号的菜单管理

C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)

C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理

C#开发微信门户及应用(17)-微信企业号的通讯录管理开发之部门管理

C#开发微信门户及应用(16)-微信企业号的配置和使用

C#开发微信门户及应用(15)-微信菜单增加扫一扫、发图片、发地理位置功能

 C#开发微信门户及应用(14)-在微信菜单中采用重定向获取用户数据

C#开发微信门户及应用(13)-使用地理位置扩展相关应用

C#开发微信门户及应用(12)-使用语音处理

C#开发微信门户及应用(11)--微信菜单的多种表现方式介绍

C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息

C#开发微信门户及应用(9)-微信门户菜单管理及提交到微信服务器

C#开发微信门户及应用(8)-微信门户应用管理系统功能介绍

C#开发微信门户及应用(7)-微信多客服功能及开发集成

C#开发微信门户及应用(6)--微信门户菜单的管理操作

C#开发微信门户及应用(5)--用户分组信息管理

C#开发微信门户及应用(4)--关注用户列表及详细信息管理

C#开发微信门户及应用(3)--文本消息和图文消息的应答

C#开发微信门户及应用(2)--微信消息的处理和应答

C#开发微信门户及应用(1)--开始使用微信接口

本文转自博客园伍华聪的博客,原文链接:C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密,如需转载请自行联系原博主。



目录
相关文章
|
2月前
|
自然语言处理 搜索推荐 小程序
微信公众号接口:解锁公众号开发的无限可能
微信公众号接口是微信官方提供的API,支持开发者通过编程与公众号交互,实现自动回复、消息管理、用户管理和数据分析等功能。本文深入探讨接口的定义、类型、优势及应用场景,如智能客服、内容分发、电商闭环等,并介绍开发流程和工具,帮助运营者提升用户体验和效率。未来,随着微信生态的发展,公众号接口将带来更多机遇,如小程序融合、AI应用等。
|
14天前
|
小程序 Java 关系型数据库
weixin163基于微信小程序的校园二手交易平台系统设计与开发ssm(文档+源码)_kaic
本文介绍了一款基于微信小程序的校园二手物品交易平台的开发与实现。该平台采用Java语言开发服务端,使用MySQL数据库进行数据存储,前端以微信小程序为载体,支持管理员和学生两种角色操作。管理员可管理用户、商品分类及信息、交易记录等,而学生则能注册登录、发布购买商品、参与交流论坛等。系统设计注重交互性和安全性,通过SSM框架优化开发流程,确保高效稳定运行,满足用户便捷交易的需求,推动校园资源共享与循环利用。
|
14天前
|
小程序 关系型数据库 Java
weixin168“返家乡”高校暑期社会实践微信小程序设计与开发ssm(文档+源码)_kaic
本文探讨高校暑期社会实践微信小程序的开发与应用,旨在通过信息化手段提升活动管理效率。借助微信小程序技术、SSM框架及MySQL数据库,实现信息共享、流程规范和操作便捷。系统涵盖需求分析、可行性研究、设计实现等环节,确保技术可行、操作简便且经济合理。最终,该小程序可优化活动发布、学生信息管理和心得交流等功能,降低管理成本并提高工作效率。
|
1月前
|
人工智能 自然语言处理 小程序
技术小白如何利用DeepSeek半小时开发微信小程序?
通过通义灵码的“AI程序员”功能,即使没有编程基础也能轻松创建小程序或网页。借助DeepSeek V3和R1满血版模型,用户只需用自然语言描述需求,就能自动生成代码并优化程序。例如,一个文科生仅通过描述需求就成功开发了一款记录日常活动的微信小程序。此外,通义灵码还提供智能问答模式,帮助用户解决开发中的各种问题,极大简化了开发流程,让普通人的开发体验更加顺畅。
852 11
技术小白如何利用DeepSeek半小时开发微信小程序?
|
1月前
|
小程序 JavaScript 前端开发
微信小程序开发全流程:从注册到上线的完整指南
这篇文章详细记录了微信小程序的完整开发到最终上线的每一个步骤。适合对小程序开发感兴趣的个人开发者或希望了解完整流程的学习者,涵盖了云开发、事件绑定、生命周期管理、组件使用等关键内容。
217 11
|
1月前
百炼-我的智能体应用在微信公众号渠道无法得到输出
微信公众号,总是出现思考中,请回复“继续”,而在我的应用观测中已经体现了输出
71 0
|
1月前
|
小程序
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
145 0
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
|
2月前
|
小程序
微信小程序数据绑定与事件处理:打造动态交互体验
在上一篇中,我们学习了搭建微信小程序开发环境并创建“Hello World”页面。本文深入探讨数据绑定和事件处理机制,通过具体案例帮助你打造更具交互性的小程序。数据绑定使用双花括号`{{}}`语法,实现页面与逻辑层数据的动态关联;事件处理则通过`bind`或`catch`前缀响应用户操作。最后,通过一个简单的计数器案例,巩固所学知识。掌握这些核心技能,将助你开发更复杂的小程序。
|
2月前
|
JSON 缓存 小程序
微信小程序组件封装与复用:提升开发效率
本文深入探讨了微信小程序的组件封装与复用,涵盖组件的意义、创建步骤、属性与事件处理,并通过自定义弹窗组件的案例详细说明。组件封装能提高代码复用性、开发效率和可维护性,确保UI一致性。掌握这些技能有助于构建更高质量的小程序。
|
5月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
91 3

热门文章

最新文章