在上篇隨筆《C#開發(fā)微信門戶及應(yīng)用(19)-微信企業(yè)號(hào)的消息發(fā)送(文本、圖片、文件、語(yǔ)音、視頻、圖文消息等)》介紹了有關(guān)企業(yè)號(hào)的消息發(fā)送,官方特別聲明消息是不用加密發(fā)送的。但是在回調(diào)的服務(wù)器上,也就是我們網(wǎng)站的服務(wù)器上,微信傳過(guò)來(lái)的消息是加密的,需要我們調(diào)用類庫(kù)對(duì)消息和事件進(jìn)行解密操作,由于官方的例子不全,因此摸索了不少時(shí)間,最終順利解密收到的各種消息和事件。本文主要介紹?微信企業(yè)號(hào)的消息和事件的接收處理及解密操作。
1、企業(yè)號(hào)回調(diào)模式的設(shè)置
和公眾號(hào)一樣,微信企業(yè)號(hào)如果需要進(jìn)行二次開發(fā),也是需要在后臺(tái)設(shè)置好對(duì)應(yīng)的回調(diào)參數(shù),如下界面所示。
設(shè)置好這些后,檢查通過(guò)后,我們就可以在自己微信應(yīng)用服務(wù)器上進(jìn)行消息的收發(fā)操作了。
在回調(diào)的消息入口處,我們需要對(duì)POST數(shù)據(jù)和普通的GET數(shù)據(jù)進(jìn)行分開處理,GET數(shù)據(jù)是微信自身的驗(yàn)證處理,POST數(shù)據(jù)是微信消息的交互操作。
????///?<summary> ????///?企業(yè)號(hào)回調(diào)信息接口。統(tǒng)一接收并處理信息的入口。????///?</summary> ????public?class?corpapi?:?IHttpHandler ????{????????///?<summary> ????????///?處理企業(yè)號(hào)的信息????????///?</summary> ????????///?<param name="context"></param> ????????public?void?ProcessRequest(HttpContext?context) ????????{
上面我們定義了一個(gè)一般應(yīng)用處理程序來(lái)對(duì)消息進(jìn)行處理。
然后我們分開不同的消息類型(POST、GET 方式),針對(duì)性的進(jìn)行處理。
????????????????????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、微信回調(diào)消息的驗(yàn)證
?下面是微信對(duì)于回調(diào)模式,驗(yàn)證URL的說(shuō)明。
驗(yàn)證URL有效性
當(dāng)你提交以上信息時(shí),企業(yè)號(hào)將發(fā)送GET請(qǐng)求到填寫的URL上,GET請(qǐng)求攜帶四個(gè)參數(shù),企業(yè)在獲取時(shí)需要做urldecode處理,否則會(huì)驗(yàn)證不成功。
參數(shù) | 描述 | 是否必帶 |
---|---|---|
msg_signature | 微信加密簽名,msg_signature結(jié)合了企業(yè)填寫的token、請(qǐng)求中的timestamp、nonce參數(shù)、加密的消息體 | 是 |
timestamp | 時(shí)間戳 | 是 |
nonce | 隨機(jī)數(shù) | 是 |
echostr | 加密的隨機(jī)字符串,以msg_encrypt格式提供。需要解密并返回echostr明文,解密后有random、msg_len、msg、$CorpID四個(gè)字段,其中msg即為echostr明文 | 首次校驗(yàn)時(shí)必帶 |
企業(yè)通過(guò)參數(shù)msg_signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),如果確認(rèn)此次GET請(qǐng)求來(lái)自企業(yè)號(hào),那么企業(yè)應(yīng)用對(duì)echostr參數(shù)解密并原樣返回echostr明文(不能加引號(hào)),則接入驗(yàn)證生效,回調(diào)模式才能開啟。
后續(xù)回調(diào)企業(yè)時(shí)都會(huì)在請(qǐng)求URL中帶上以上參數(shù)(echostr除外),校驗(yàn)方式與首次驗(yàn)證URL一致。
根據(jù)上面的說(shuō)明,我們需要獲取這些參數(shù),然后調(diào)用微信提供的消息處理函數(shù)進(jìn)行加解密處理。
在驗(yàn)證URL的Auth(accountInfo);操作里面,我們可以看到核心的內(nèi)容如下所示,就是獲取到這些傳遞過(guò)來(lái)的參數(shù)信息,然后交給基類處理消息的簽名內(nèi)容。
????????????????????????#region?具體處理邏輯????????????????????????string?echoString?=?HttpContext.Current.Request.QueryString["echoStr"];????????????????????????string?signature?=?HttpContext.Current.Request.QueryString["msg_signature"];//企業(yè)號(hào)的?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
驗(yàn)證代碼部門如下所示。
????????///?<summary> ????????///?驗(yàn)證企業(yè)號(hào)簽名????????///?</summary> ????????///?<param name="token">企業(yè)號(hào)配置的Token</param> ????????///?<param name="signature">簽名內(nèi)容</param> ????????///?<param name="timestamp">時(shí)間戳</param> ????????///?<param name="nonce">nonce參數(shù)</param> ????????///?<param name="corpId">企業(yè)號(hào)ID標(biāo)識(shí)</param> ????????///?<param name="encodingAESKey">加密鍵</param> ????????///?<param name="echostr">內(nèi)容字符串</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、企業(yè)號(hào)的消息處理
?上面介紹了,微信企業(yè)號(hào)對(duì)URL的驗(yàn)證過(guò)程,還有另外一個(gè)消息處理過(guò)程,就是微信服務(wù)器把消息發(fā)送給我們自己的應(yīng)用服務(wù)器進(jìn)行處理的過(guò)程,我們應(yīng)用服務(wù)器需要在收到消息后,及時(shí)進(jìn)行常規(guī)回復(fù)處理。
也就是下面的代碼邏輯。
????????????????????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); ????????????????????????} ????????????????????}
同樣,我們給微信服務(wù)器回應(yīng)消息的時(shí)候,我們也需要獲得相應(yīng)的參數(shù),然后再行構(gòu)造信息回答。
????????????string?echoString?=?HttpContext.Current.Request.QueryString["echoStr"];????????????string?signature?=?HttpContext.Current.Request.QueryString["msg_signature"];//企業(yè)號(hào)的?msg_signature ????????????string?timestamp?=?HttpContext.Current.Request.QueryString["timestamp"];????????????string?nonce?=?HttpContext.Current.Request.QueryString["nonce"];
而另外一些參數(shù)信息,則是來(lái)源于我們企業(yè)號(hào)賬號(hào)的配置參數(shù)。
????????????//獲取配置參數(shù)并對(duì)加解密函數(shù)初始化 ????????????string?CorpToken?=?accountInfo.Token;????????????string?AESKey?=?accountInfo.EncodingAESKey;????????????string?CorpId?=?accountInfo.CorpID;
然后使用微信提供的消息加解密類,就可以順利對(duì)消息進(jìn)行加解密的處理了。具體操作代碼如下所示。
????????????//根據(jù)參數(shù)信息,初始化微信對(duì)應(yīng)的消息加密解密類 ????????????WXBizMsgCrypt?wxcpt?=?new?WXBizMsgCrypt(CorpToken,?AESKey,?CorpId);????????????//對(duì)收到的密文進(jìn)行解析處理 ????????????string?sMsg?=?"";??//?解析之后的明文 ????????????int?flag?=?wxcpt.DecryptMsg(signature,?timestamp,?nonce,?postStr,?ref?sMsg);????????????if?(flag?==?0) ????????????{????????????????//LogTextHelper.Info("記錄解密后的數(shù)據(jù):");????????????????//LogTextHelper.Info(sMsg);//記錄解密后的數(shù)據(jù) ????????????????CorpApiDispatch?dispatch?=?new?CorpApiDispatch();????????????????string?responseContent?=?dispatch.Execute(sMsg);????????????????//加密后并發(fā)送????????????????//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("解密消息失??!"); ????????????}
最終,我們把解密完成的消息交給對(duì)應(yīng)的封裝類進(jìn)行統(tǒng)一處理就可以了。
????????????????CorpApiDispatch?dispatch?=?new?CorpApiDispatch();????????????????string?responseContent?=?dispatch.Execute(sMsg);
這樣我們?cè)谄髽I(yè)號(hào)API的封裝,就可以只需要關(guān)注消息如何應(yīng)答的邏輯就可以了,其他的不用關(guān)心。
?
?
更多C#開發(fā)微信門戶及應(yīng)用-微信企業(yè)號(hào)的消息和事件的接收處理及解密?相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)