微信公眾號開發C#系列-2、微信公眾平臺接入指南

概述
微信公眾平臺消息接口的工作原理大概可以這樣理解:從用戶端到公眾號端一個流程是這樣的,用戶發送消息到微信服務器,微信服務器將接收到的消息post到用戶接入時填寫的url中,在url處理程序中,首先判斷消息的合法性,判斷成功后根據消息體的內容做相應的處理。原理很容易理解,接觸過socket的可能理解起來更容易。對于微信開發者模式的接入官網文檔非常的簡潔,對于初學者很多都摸不著頭腦,微信官方技術文檔的接入指南可以參考接入指南
大致步驟就是:
- 填寫服務器配置
- 驗證服務器地址的有效性
- 依據接口文檔實現業務邏輯
準備工作
要接入微信,首先我們需要一個微信公眾號,相信做微信公眾號開發的朋友都會遇到這樣的問題,就是微信公眾號提供的接口權限問題。如果是個人訂閱號,官方提供的接口很少,很多接口都不能用。如果想測試接口功能怎么辦?其實,微信公眾號官方給我們提供一個微信公眾測試號,測試號除了不能用微信支付接口,其他接口基本都可以用獲取并且可以使用。下面我就教大家如何申請微信公眾號測試號。全微信掃一掃公眾平臺測試賬號系統登錄即可,非常的方便。微信公眾平臺測試賬號系統地址:公眾平臺測試賬號系統登錄后我們就可以輕松愉快的進行下面的玩耍了。對于常規的微信公眾號接入方式與測試公眾號大同小異,這兒成功了其他的類似。
填寫服務器配置與驗證消息的確來自微信服務器
- 填寫服務器配置
在填寫服務器配置之前我們需要了解一下微信與我們的服務器交互的過程:
當我們在微信app上,給公眾號發送一條消息時,這條消息實際上是發送到了微信的服務器上,此時微信的服務器就會對消息進行封裝成某種格式的數據比如xml格式,再轉發到我們配置好的URL上,所以該URL實際就是我們處理數據的一個請求路徑。因此該URL必須是能暴露給外界訪問的一個公網地址,不能使用內網地址,生產環境可以申請騰訊云,阿里云服務器等,但在開發環境中可暫時利用一些軟件來完成內網穿透以便于修改和測試,如NATAPP,花生殼等軟件,使用起來也很方便,在本地安裝對應的軟件,配置運行后,直接使用軟件分配的臨時域名來訪問本地應用即可,只是偶爾會存在網絡不穩定的情況,具體的外網映射工具與調試的方法后面的文章我們會接受。

有了這樣一個基本的概念后,我們看下接口配置信息相關的說明。
接口配置如下圖所示:

對于測試號信息中的appid與appsecret兩個屬性是唯一的標識,每個測試號都會有自己的appid與appsecret ,是比較重要的信息,不要隨意發給別人。
- appid:是公眾號開發識別碼,配合開發者密碼可調用公眾號的接口能力。
- appsecret:是校驗公眾號開發者身份的密碼,具有極高的安全性。
服務器地址URL是開發者用來接收微信消息和事件的接口URL,是我們服務器的響應微信請求的地址。
假設我們自己的服務器域名是www.rdiframework.net,準備用/WeiXin/WeChat/來接收消息,就填寫:
http://www.rdiframework.net/WeiXin/WeChat/
Token可以任意填寫,為了安全性和防止黑客攻擊建議設置得復雜一些,并要防止泄露。
測試號一般只需要填寫URL與Token兩項內容,真實項目的填寫還要填寫EncodingAESKey,可以由開發者手動填寫或隨機生成,將用作消息體加解密密鑰。
開發者還可選擇消息加解密方式:明文模式、兼容模式和安全模式,具體可參看開發者文檔。
另請注意,微信公眾號接口地址必須以http://或https://開頭,分別支持80端口和443端口。
- 驗證消息的確來自微信服務器
當我們填入url與token的值,并提交后,微信會發送一個get請求到我們填寫的url上,并且攜帶4個參數,而signature參數結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數來做的加密簽名,我們在后臺需要對該簽名進行校驗,看是否合法。實際上,我們發現微信帶過來的4個參數中并沒有帶token參數,僅有signature是和token有關的,所以我們應該在本地應用中也準備一個和填入的token相同的參數,再通過微信傳入的timestamp與nonce做相同算法的加密操作,若結果與微信傳入的signature相同,即為合法,則原樣返回echostr參數,代表接入成功,否則不做處理,則接入失敗。
詳細流程可參考微信官方提供的邏輯流程圖,我們的應用需要以該流程圖的步驟來實現。

下面為我們以.NET MVC代碼實現get請求樣例代碼,可供參考:
[HttpGet]
[ActionName("Index")]
public Task<ActionResult> Get(string signature, string timestamp, string nonce, string echostr)
{
return Task.Factory.StartNew(() =>
{
if (CheckSignature.Check(signature, timestamp, nonce, "WeiXinToken"))
{
return echostr; //返回隨機字符串則表示驗證通過
}
else
{
return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, weixinOfficialAccountEntity.Token) + "。" + "如果你在瀏覽器中看到這句話,說明此地址可以被作為微信公眾賬號后臺的Url,請注意保持Token一致。";
}
}).ContinueWith<ActionResult>(task => Content(task.Result));
}
上面的代碼注意token不是微信服務器發過來的,而是我們自己寫死的一個常量,就是在微信后臺填寫的Token,這兒我填寫的是:WeiXinToken
依據接口文檔實現業務邏輯
驗證URL有效性成功后我們就可以接收來自微信的數據,并對接收到的數據按需做相應的業務處理。用戶每次向公眾號發送消息、或者產生自定義菜單、或產生微信支付訂單等情況時,開發者填寫的服務器配置URL將得到微信服務器推送過來的消息和事件,開發者可以依據自身業務邏輯進行響應,如回復消息。
公眾號調用各接口時,一般會獲得正確的結果,具體結果可見對應接口的說明。返回錯誤時,可根據返回碼來查詢錯誤原因。全局返回碼說明
微信后臺發送消息是一個POST請求,但和普通的POST請求不同的是,首先,URL會帶上signature、timestamp、nonce這3個參數:
POST http://www.rdiframework.net/WeiXin/WeChat/?signature=xxx×tamp=123456&nonce=123
然后,HTTP請求的BODY是一個不規范的XML:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
我們自己的服務器只需要處理該XML,然后,向微信返回一個類似如下的XML:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
就可以完成消息的回復。微信后臺要求必須在5秒內回復,最多重試3次,否則我們自己的回復消息就到達不了用戶的手機了。如果我們自己的服務器無法在5秒內回復,就回復一個空字符串,告訴微信服務器,不用重試了,這個消息處理不了,不給用戶回復了。
上面的交互邏輯看起來很簡單,但實際上坑有很多。
首先,微信服務器發送的POST請求根本就不符合HTTP規范。原則上POST請求不應該在URL上附帶參數,但微信后臺偏偏要這么干,這就讓很多編程語言的標準框架無法獲取到POST參數,因為標準的POST參數是從HTTP BODY中解析的。所以從POST獲取URL參數就需要用到更底層的代碼?,F在無論做什么都講究的是效率,什么東西有現成的我們就不需要去重復的造輪子,直接拿來使用即可。在.net下微信開發我們推薦使用開源的SENPARC.WEIXIN SDK,這個sdk基本完成了微信全系列的操作功能,使用的客戶多,一直在升級中,可放心使用。簡單的幾行代碼就可以實現一個功能,何樂而不為呢。
接收微信的請求代碼參考:
[HttpPost]
[ActionName("Index")]
public Task<ActionResult> Post(PostModel postModel)
{
return Task.Factory.StartNew<ActionResult>(() =>
{
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, "WeiXinToken"))
{
return new WeixinResult("參數錯誤!");
}
postModel.Token = "****Token***";
postModel.EncodingAESKey = "***EncodingAESKey***"; //根據自己后臺的設置保持一致
postModel.AppId = "****AppId***"; //根據自己后臺的設置保持一致
//自定義MessageHandler,對微信請求的詳細判斷操作都在這里面。
var messageHandler = new CustomMessageHandler(Request.InputStream, postModel,10);
messageHandler.Execute(); //執行微信處理過程
return new FixWeixinBugWeixinResult(messageHandler);
}).ContinueWith<ActionResult>(task => task.Result);
}
吐槽:微信和微信公眾平臺雖然產品很先進,但后臺API設計得確實不咋地。由于API是給開發人員使用的,所以,設計一個好的API要從開發人員的角度出發。與其使用笨重的XML,不如使用更符合Web潮流的JSON。
例如驗證服務器:
{
"signature": "xxx",
"timestamp": 123456,
"nonce": "xxx",
"action": "verify",
"data": {
"echostr": "echo"
}
}
這樣設計的API,各種編程語言都能處理,而且處理邏輯更簡單,速度更快。
參考文章
RDIFramework.NET — 基于.NET的快速信息化系統開發框架 — 系列目錄
RDIFramework.NET ━ .NET快速信息化系統開發框架 ━ 工作流程組件介紹
RDIFramework.NET框架SOA解決方案(集Windows服務、WinForm形式與IIS形式發布)-分布式應用
RDIFramework.NET代碼生成器全新V3.5版本發布-重大升級
一路走來數個年頭,感謝RDIFramework.NET框架的支持者與使用者,大家可以通過下面的地址了解詳情。
RDIFramework.NET官方網站:http://www.rdiframework.net/
RDIFramework.NET官方博客:http://blog.rdiframework.net/
同時需要說明的,以后的所有技術文章以官方網站為準,歡迎大家收藏!
RDIFramework.NET框架由專業團隊長期打造、一直在更新、一直在升級,請放心使用!
歡迎關注RDIFramework.net框架官方公眾微信(微信號:guosisoft),及時了解最新動態。
掃描二維碼立即關注

作者:
RDIF
出處:
http://www.rzrgm.cn/huyong/
Email:
406590790@qq.com
QQ:
406590790
微信:
13005007127(同手機號)
框架官網:
http://www.guosisoft.com/
http://www.rdiframework.net/
框架其他博客:
http://blog.csdn.net/chinahuyong
http://www.rzrgm.cn/huyong
國思RDIF開發框架
,
給用戶和開發者最佳的.Net框架平臺方案,為企業快速構建跨平臺、企業級的應用提供強大支持。
關于作者:系統架構師、信息系統項目管理師、DBA。專注于微軟平臺項目架構、管理和企業解決方案,多年項目開發與管理經驗,曾多次組織并開發多個大型項目,在面向對象、面向服務以及數據庫領域有一定的造詣。現主要從事基于
RDIF
框架的技術開發、咨詢工作,主要服務于金融、醫療衛生、鐵路、電信、物流、物聯網、制造、零售等行業。
如有問題或建議,請多多賜教!
本文版權歸作者和CNBLOGS博客共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,如有問題,可以通過微信、郵箱、QQ等聯系我,非常感謝。

當我們在微信app上,給公眾號發送一條消息時,這條消息實際上是發送到了微信的服務器上,此時微信的服務器就會對消息進行封裝成某種格式的數據比如xml格式,再轉發到我們配置好的URL上,所以該URL實際就是我們處理數據的一個請求路徑。因此該URL必須是能暴露給外界訪問的一個公網地址,不能使用內網地址,生產環境可以申請騰訊云,阿里云服務器等,但在開發環境中可暫時利用一些軟件來完成內網穿透以便于修改和測試,如NATAPP,花生殼等軟件,使用起來也很方便,在本地安裝對應的軟件,配置運行后,直接使用軟件分配的臨時域名來訪問本地應用即可,只是偶爾會存在網絡不穩定的情況,具體的外網映射工具與調試的方法后面的文章我們會接受。
浙公網安備 33010602011771號