1. Setting of the callback mode of the enterprise account
Like the public account, if the WeChat enterprise account requires secondary development, the corresponding callback parameters need to be set in the background, as shown in the following interface.
After setting these and passing the check, we can send and receive messages on our WeChat application server.
At the callback message entry, we need to process POST data and ordinary GET data separately. GET data is WeChat's own verification processing, and POST data is the interactive operation of WeChat messages.
/// <summary> /// 企业号回调信息接口。统一接收并处理信息的入口。 /// </summary> public class corpapi : IHttpHandler { /// <summary> /// 处理企业号的信息 /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) {
Above we defined a general application handler to process messages.
Then we separate different message types (POST, GET methods) and process them accordingly.
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); }
The following is WeChat’s description of callback mode and verification URL.
Verify URL validity
When you submit the above information, the enterprise account will send a GET request to the filled-in URL. The GET request carries four parameters,Enterprises need to perform urldecode processing when obtaining , otherwise the verification will fail.
Parameter | Description | Is it required |
---|---|---|
msg_signature | WeChat encrypted signature, msg_signature combines the token filled in by the enterprise, the timestamp, nonce parameter in the request, and the encrypted message body | is |
timestamp | Timestamp | is |
nonce | Random number | is |
Encrypted random string, provided in msg_encrypt format. It is necessary to decrypt and return the echostr plaintext. After decryption, there are four fields: random, msg_len, msg, and $CorpID. msg is the echostr plaintext. | must be included in the first verification. |
The enterprise application decrypts the echostr parameter and returns the echostr plaintext as it is (no quotes), then The callback mode can be enabled only after access verification takes effect.
When subsequent callbacks are made to the enterprise, the above parameters (except echostr) will be included in the request URL, and the verification method is consistent with the first verification URL. According to the above instructions, we need to obtain these parameters, and then call the message processing function provided by WeChat to perform encryption and decryption processing. In the Auth(accountInfo); operation of verifying the URL, we can see that the core content is as follows, which is to obtain the passed parameter information and then hand it over to the base class to process the signature content of the message.#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; }
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);