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); }
下面是微信對於回呼模式,驗證URL的說明。
驗證URL有效性
當你提交以上資訊時,企業號將發送GET請求到填寫的URL上,GET請求攜帶四個參數,企業在取得時需要做urldecode處理,否則會驗證不成功。
參數 | 描述 | 是否必帶 |
---|---|---|
微信加密簽名,msg_signature結合了企業填寫的token、請求中的timestamp、nonce參數、加密的訊息體 | 是 | |
時間戳 | 是 | |
隨機數字 | 是 | |
加密的隨機字串,以msg_encrypt格式提供。需要解密並回傳echostr明文,解密後有random、msg_len、msg、$CorpID四個字段,其中msg即為echostr明文 | 首次校驗時必帶 |
企業應用對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; }
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);