echostr | 暗号化されたランダムですmsg_encrypt 形式で提供される文字列。 echostr 平文を復号して返す必要があります。random、msg_len、msg、$CorpID は最初の検証に含める必要があります。企业通过参数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#开发微信门户及应用-微信企业号的消息和事件的接收处理及解密 相关文章请关注PHP中文网!