天天看點

微信公衆号開發C#系列-2、微信公衆平台接入指南

微信公衆号開發C#系列-2、微信公衆平台接入指南

當我們在微信app上,給公衆号發送一條消息時,這條消息實際上是發送到了微信的伺服器上,此時微信的伺服器就會對消息進行封裝成某種格式的資料比如xml格式,再轉發到我們配置好的URL上,是以該URL實際就是我們處理資料的一個請求路徑。是以該URL必須是能暴露給外界通路的一個公網位址,不能使用内網位址,生産環境可以申請騰訊雲,阿裡雲伺服器等,但在開發環境中可暫時利用一些軟體來完成内網穿透以便于修改和測試,如NATAPP,花生殼等軟體,使用起來也很友善,在本地安裝對應的軟體,配置運作後,直接使用軟體配置設定的臨時域名來通路本地應用即可,隻是偶爾會存在網絡不穩定的情況,具體的外網映射工具與調試的方法後面的文章我們會接受。

微信公衆号開發C#系列-2、微信公衆平台接入指南

概述

微信公衆平台消息接口的工作原理大概可以這樣了解:從使用者端到公衆号端一個流程是這樣的,使用者發送消息到微信伺服器,微信伺服器将接收到的消息post到使用者接入時填寫的url中,在url處理程式中,首先判斷消息的合法性,判斷成功後根據消息體的内容做相應的處理。原理很容易了解,接觸過socket的可能了解起來更容易。對于微信開發者模式的接入官網文檔非常的簡潔,對于初學者很多都摸不着頭腦,微信官方技術文檔的接入指南可以參考接入指南

大緻步驟就是:

  1. 填寫伺服器配置
  2. 驗證伺服器位址的有效性
  3. 依據接口文檔實作業務邏輯

準備工作

要接入微信,首先我們需要一個微信公衆号,相信做微信公衆号開發的朋友都會遇到這樣的問題,就是微信公衆号提供的接口權限問題。如果是個人訂閱号,官方提供的接口很少,很多接口都不能用。如果想測試接口功能怎麼辦?其實,微信公衆号官方給我們提供一個微信公衆測試号,測試号除了不能用微信支付接口,其他接口基本都可以用擷取并且可以使用。下面我就教大家如何申請微信公衆号測試号。全微信掃一掃公衆平台測試賬号系統登入即可,非常的友善。微信公衆平台測試賬号系統位址:公衆平台測試賬号系統登入後我們就可以輕松愉快的進行下面的玩耍了。對于正常的微信公衆号接入方式與測試公衆号大同小異,這兒成功了其他的類似。

填寫伺服器配置與驗證消息的确來自微信伺服器

在填寫伺服器配置之前我們需要了解一下微信與我們的伺服器互動的過程:

微信公衆号開發C#系列-2、微信公衆平台接入指南

有了這樣一個基本的概念後,我們看下接口配置資訊相關的說明。

接口配置如下圖所示:

微信公衆号開發C#系列-2、微信公衆平台接入指南

對于測試号資訊中的appid與appsecret兩個屬性是唯一的辨別,每個測試号都會有自己的appid與appsecret ,是比較重要的資訊,不要随意發給别人。

  1. appid:是公衆号開發識别碼,配合開發者密碼可調用公衆号的接口能力。
  2. 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參數,代表接入成功,否則不做處理,則接入失敗。

詳細流程可參考微信官方提供的邏輯流程圖,我們的應用需要以該流程圖的步驟來實作。

微信公衆号開發C#系列-2、微信公衆平台接入指南

下面為我們以.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&timestamp=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參數就需要用到更底層的代碼。現在無論做什麼都講究的是效率,什麼東西有現成的我們就不需要去重複的造輪子,直接拿來使用即可。在.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,各種程式設計語言都能處理,而且處理邏輯更簡單,速度更快。

參考文章

微信公衆平台技術文檔-官方

Senparc.Weixin SDK + 官網示例源代碼

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),及時了解最新動态。

掃描二維碼立即關注

微信公衆号開發C#系列-2、微信公衆平台接入指南

作者:

RDIFramework.NET

出處:http://www.cnblogs.com/huyong/

Email:[email protected]

QQ:406590790

微信:13005007127(同手機号)

架構官網:http://www.rdiframework.net/

架構官網部落格:http://blog.rdiframework.net/

架構其他部落格:http://blog.csdn.net/chinahuyong

http://www.cnblogs.com/huyong

RDIFramework.NET,基于全新.NET Framework與.NET Core的快速資訊化系統開發、整合架構,為企業快速建構垮平台、企業級的應用提供了強大支援。

關于作者:系統架構師、資訊系統項目管理師、DBA。專注于微軟平台項目架構、管理和企業解決方案,多年項目開發與管理經驗,曾多次組織并開發多個大型項目,在面向對象、面向服務以及資料庫領域有一定的造詣。現主要從事基于

RDIFramework.NET

架構的技術開發、咨詢工作,主要服務于金融、醫療衛生、鐵路、電信、物流、物聯網、制造、零售等行業。

如有問題或建議,請多多賜教!

本文版權歸作者和CNBLOGS部落格共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,如有問題,可以通過微信、郵箱、QQ等聯系我,非常感謝。