Dans l'essai précédent "Développement C# du portail et de l'application WeChat (19) - Envoi de messages des comptes d'entreprise WeChat (texte, images, fichiers, voix, vidéo, messages graphiques, etc.)" a introduit l'envoi de messages des comptes d'entreprise , Les responsables déclarent spécifiquement que les messages sont envoyés sans cryptage. Mais sur le serveur de rappel, qui est le serveur de notre site Web, les messages envoyés depuis WeChat sont cryptés et nous devons appeler la bibliothèque de classes pour décrypter les messages et les événements. Les exemples officiels étant incomplets, nous avons passé beaucoup de temps. exploration Enfin, divers messages et événements reçus ont été décryptés avec succès. Cet article présente principalement les opérations de réception, de traitement et de décryptage des messages et événements sur les comptes WeChat Enterprise.
Identique au compte officiel, si le compte d'entreprise WeChat nécessite un développement secondaire, il doit également définir les paramètres de rappel correspondants en arrière-plan, comme indiqué dans l'interface suivante.
Après les avoir définis et passé le contrôle, nous pouvons envoyer et recevoir des messages sur notre propre serveur d'applications WeChat.
Lors de l'entrée du message de rappel, nous devons traiter séparément les données POST et les données GET ordinaires. Les données GET sont le propre traitement de vérification de WeChat, et les données POST sont le fonctionnement interactif des messages WeChat.
/// <summary> /// 企业号回调信息接口。统一接收并处理信息的入口。 /// </summary> public class corpapi : IHttpHandler { /// <summary> /// 处理企业号的信息 /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) {
Ci-dessus, nous avons défini un gestionnaire d'application général pour traiter les messages.
Ensuite, nous séparons les différents types de messages (méthodes POST, GET) et les traitons en conséquence.
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); }
Voici les instructions de WeChat pour le mode de rappel et l'URL de vérification.
Vérifier la validité de l'URL
Lorsque vous soumettez les informations ci-dessus, le compte d'entreprise enverra une requête GET à l'URL renseignée. La requête GET comporte quatre paramètres, Les entreprises doivent effectuer un traitement de décodage d'URL lors de l'obtention de , sinon la vérification échouera.
参数 | 描述 | 是否必带 |
---|---|---|
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; }
上面介绍了,微信企业号对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中文网!