關於.NetCore中第三方開放平臺接受微信推送的授權消息以及事件消息

如何處理微信開放平臺中微信推送的消息


爲什麼還要寫微信消息接收的文章

          最近項目由.net framework框架升級到了Core

          客戶有新的需求,需要統計公衆號取消關注人數以及新增粉絲數,需要用到事件消息接收

          上一篇文章寫的不夠詳細,依然有很多人問我,應該怎麼處理微信授權消息

複習要點

  1. 如何在Core2.0中處理授權事件接收消息
  2. 如何在Core2.0中處理消息與事件接收消息      

正文


爲什麼我們需要處理微信推送的消息

  1. 授權事件接受的消息,主要用於獲取或者刷新授權公衆號的授權信息,主要是AccessToken
  2. 消息與事件接受的消息,有兩部分作用:
  • 申請微信開放平臺時,權限選擇部分,在公衆號權限中,如果選擇了消息管理權限,即:幫助公衆號接收用戶消息,進行人工客服回覆或自動回覆。那麼所有用戶消息將會推送至該Url
  • 用戶事件消息,即用戶行爲消息,也會推送至該Url,如,關注公衆號,取消關注公衆號,覈銷卡劵,刪除卡劵等

我們如何處理微信推送消息

    開發資料填寫


  1. 申請微信開放平臺,在填寫開發資料步驟,我們需要填寫如下內容:
  • 授權發起頁域名。建議填寫頂級域名,如:www.xxxx.com/www.xxxx.cn;針對這個域名的解釋很清晰:必須從本域名內網頁跳轉到登錄授權頁,纔可完成登錄授權。無需填寫http://等域名協議前綴。必須從本域名內網頁跳轉至登錄授權頁。也就是說,公衆號授權必須從該域名發起或者該域名的子域名發起。爲了更靈活的配置開放平臺的發起域名信息,我建議在這裏填寫頂級域名。畢竟我們的頂級域名只有一個,二級域名可以隨意創建。
  • 授權測試公衆號列表。我們可以隨意填寫一個本公司用於測試的微信公衆號的原始ID,請注意,是原始ID,並非AppId。在開放平臺未發佈成功之前,我們可以使用該測試公衆號測試我們的代碼是否正確無漏洞。
  • 授權事件接收URL。這個地址,是我們這篇文章介紹的重點之一。微信的解釋如下:用於接收取消授權通知、授權成功通知、授權更新通知,也用於接收ticket,ticket是驗證平臺方的重要憑據。
  • 消息校驗Token。我們接受到的所有消息,事件消息,用戶消息,以及授權通知消息,ticket消息等,我們都需要使用該Token校驗消息的合法性。
  • 消息加解密Key。微信推送給開放平臺的所有消息都經過了加密處理,我們需要使用該Key,對消息進行解密,獲取消息體內容。
  • 消息與事件接收URL。這個地址,也是我們這篇文章介紹的重點之一,微信的解釋如下:通過該URL接收公衆號或小程序消息和事件推送,該參數按規則填寫(需包含/$APPID$,如www.abc.com/$APPID$/callback),實際接收消息時$APPID$將被替換爲公衆號或小程序AppId。這個地址在填寫時,必須包含/$APPID$,如:https://www.xxxx.com/Receive/EventMessage/$APPID$
  • 公衆號開發域名。同樣建議填寫頂級域名,畢竟我們的開放平臺部署完成之後,我們需要代公衆號實現業務,代公衆號做H5小遊戲與粉絲互動,當我們需要粉絲分享至朋友圈或者需獲取粉絲位置信息時,我們需要調用微信JS接口。注意:使用開放平臺獲取的公衆號Acctoken,做微信Js接口數字簽名時,做簽名的頁面的Url地址必須與公衆號開發域名一致,或爲該開發域名的二級域名。所以,在這裏,我同樣建議填寫頂級域名。

    授權事件接收URL


    首先這個地址所屬域名必須與授權發起頁域名保持一致,如:授權發起頁域名爲:www.xxxx.com。那我們的授權事件接收Url      則爲https://www.xxxx.com/Receive/SysMessage

    在這個Url中,我們將會接受兩種類型的消息。授權通知消息跟ticket消息。

  • 在全網發佈之前,我們只會接受到ticket消息。該ticket消息很重要,是我們獲取授權公衆號Acctoken的主要憑據。
  • 在全網發佈之後,我們還會接受到微信公衆號的授權通知,取消授權通知以及更新授權通知。

    消息接收

     我們先通過日誌,分析一下微信是怎麼請求我們這個接口的,通過日誌我們發現;微信實際請求的地址爲:

 http://www.xxxx.com/Receive/SysMessage?signature=692ded0848127c81dc46da67bb7cb14925we51ee&timestamp=1568969944&nonce=1382428071&encrypt_type=aes&msg_signature=f6ee103a5c0189444778bfe9c19e13ewe44790ed

    同時,還推送給我們一段文件流信息,信息內容如下:

<xml>
<AppId><![CDATA[wx1ab295c5c21ab302]]></AppId>
<Encrypt><![CDATA[sZax/4ZVbkyt2ukHDGDTg5G5p7LSn2VyycjYcXngIWElTr0suFA41SyAeNNwAy/UNmk9cUjzmYFlYrDf3zM7YObDgxP9zJBa1Y9yIWb6iluKBr3rc2P5/NQwhyESSpNPf/HgyQ3jNxMPnzAMxyGkwD3e3L0cjLQLN2PT8ICHKB8lHddJzdQJdxsTZ+Ihxkip6KSMmkT5li4DlY/eBmBwaG2nLZCM6NGFPhYVe0TDOS5i8yohyeD5Vs48i5gDmUe5EqPNvG6bJi1xUlikVLxIFZJGJkGHOurRjM8avK4mj8z3R3kKO312122/svkaBM6sQYjYf79lxNNuU6/IPByWt6Vtrf5rp2N0ccnaXmVp4lxrjkaUBrLJ2DkLxwblsWHRu/taE2wyRBUr121ohGJEBO2itsY4Qk/MZ6Sbi+qjKA6irUQedwnBy0ajPZx9GbWGILWL8sQkFNm6K9AnPJdeViw==]]></Encrypt>
</xml>
  1. 通過分析,我們得到如下結論:
  • 微信請求授權事件Url時,帶了五個參數,分別爲:Signature,Timestamp,Nonce,Encrypt_type,Msg_Signature
  • 同時還Post了一段需要解密的Xml流文件。

      爲避免第一次接觸Core2.0的同學踩到跟我一樣的坑,我分享一下怎麼接收流文件以及參數。

     參數部分,我們正常接收即可,流文件,用 Request.GetRequestMemoryStream()正常接收即可。關於參與部分,我們可以         封裝成一個實體對象接收,也可以單個參數接受。

     接收流文件一定要注意,在Core中,流文件僅允許讀取一次,故,我第一次接收到流文件之後,讀取並打印出來之後,導致         後邊的程序一直無法讀取流文件,程序一直報錯,後來才瞭解到這個機制。我們想要重複接收流文件怎麼辦?

  • 第一,我們可以將這段流文件先讀取出來,存儲在內存中,或者直接轉換爲XMLDocument對象,存儲下來。
  • 第二,我們可以在讀取流文件之前,加入如下代碼
HttpContext.Request.EnableRewind();
HttpContext.Request.Body.Position = 0;
HttpContext.Request.Body.Seek(0, 0);

   消息處理

   我們需要對接收到的消息,進行解密處理,並獲取到ticket,這個纔是我們的最終目的。

   我們在解密之前,有兩件事情需要處理

  • 部署緩存數據服務(Redise或者Memcached)
  • 在開放平臺的資源中心下載微信提供的SDK

      我們通過分析微信提供給我們的SDK,得知,解密XML文件我們需要初始化對象WXBizMsgCrypt。該類包含一個三個參數的構  造函數,參數分別爲:Token,EncodingAESKey,AppId。這三個參數微信在推送消息時,均提供給了我們。直接拿來使用即可。

       同時,在WXBizMsgCrypt對象中,提供了DecryptMsg方法,用於校驗消息的合法性並返回解密結果。該方法包含5個參數,分別爲sMsgSignature,sTimeStamp,sNonce,sPostData,返回sMsg。

參數名稱 參數描述 來源
Msg_Signature 簽名 推送消息接收的參數
Timestamp 時間戳 推送消息接收的參數
Nonce 隨機數 推送消息接收的參數
postDataStr 流文件Xml XML文件直接ToString()即可

 

直接調用,返回的sMsg即爲我們最終想要的結果:

四種授權通知消息,解密後的結果不同,我就不一一列舉了。這個節點還算清晰。

<?xml version="1.0" encoding="utf-8"?>
<xml>
  <AppId><![CDATA[wx1ab295c5cc7ab302]]></AppId>
  <CreateTime>1569168398</CreateTime>
  <InfoType><![CDATA[component_verify_ticket]]></InfoType>
  <ComponentVerifyTicket><![CDATA[ticket@@@PVIT0tApDDwt8UkCwqeF1O9ZongIK-y0pltF-WNO9OOT5eyewYOQoWg8hvU5vP2b9_YN9velMRqzSxr10trcMA]]></ComponentVerifyTicket>
</xml>

我們主要通過InfoType來區分,消息類型。這裏我着重說明一下component_verify_ticket消息。

我的處理方式是,當接受到component_verify_ticket消息之後,我會將ticket消息寫入文本文件。並根據推送消息不停覆蓋該文本。因爲ticket可是我們管理公衆號的重要憑據。

如果有公衆號開發經驗的話,我們都知道,獲取有關公衆號的所有信息,我們都需要用到acctoke這個票據。而ticket是我們使用開放平臺換取acctoken的重要憑據。那我們應該怎麼通過ticke換取Token留在開放平臺管理公衆號文章中再詳細說明,本文僅介紹如何處理微信推送的授權消息。

至此,我們的授權事件接收就算處理完了。

    消息與事件接收URL


     同樣,這個地址所屬域名必須與授權發起頁域名保持一致,如:授權發起頁域名爲:www.xxxx.com。那我們的消息與事件接收Url  則爲https://www.xxxx.com/Receive/EventMessage

    在這個Url中,同樣,我們也會接受兩種類型的消息。

  • 如果在開放平臺權限選擇部分,我們選擇了消息管理權限,那我們將會接收到粉絲髮送給公衆號的所有消息,包括,文本,視頻,圖片,語音等消息
  • 事件消息,用戶關注,用戶取消關注,公衆號獲取位置信息等等

   消息接收

  同樣,我們先分析日誌,分析一下微信是怎麼請求我們這個接口的,通過日誌我們發現;微信實際請求的地址爲:

 http://www.xxxx.com/Receive/EventMessage/wxf50cbe181c823526?signature=afab092b6ed320aaadb5e84025e868bbbf86b78b&timestamp=1569109822&nonce=1958085416&openid=oAvaB1N8afpZuAh5D7IgTGn9Zdlc&encrypt_type=aes&msg_signature=836e160d6921243851e5c121d7bc83aa3fde67ea

  同授權消息不同的是,微信直接請求的地址後,帶了公衆號的AppId,故,請一定要配置好我們的路由規則。

 同時,還推送給我們一段文件流信息,信息內容如下:

<xml>
    <AppId><![CDATA[wx1ab295c5cc7ab302]]></AppId>
    <Encrypt><![CDATA[xbG1dATam7xUScgz4bzSJRWeJgeS0mPwBFAW9F+0wJaKIkKoVjq0NItzl7MztokiuYpoNSRdiRXuQUivFTB3yZG36hgBcBPN8wPTbdOH+Xfb70fJdw8CQDuYqY8fqyRREMBpeFujzQvprnVUM0S/bar/RSwl8Uzu/kHfUnvTEOK6rjvQgJmJ1sZr+JoLcw4SC5+W42ByHNKkIrZWckV/Z5sSQeDQJwAPG4+ir6+IHU24B6+b/9JtSC5TpeF0tfgljMyOkY6OVmolqjlnWno9M2ppEEIgxsx5CKjcb7MMgqIAD4ptiwjDuH9O3p23ZvYogjxVNUpKfcuXS2abS6fS2q8YjbDYRyIn8gj5YnWUVy3784zBH1hJqdUNzlFylasn34oCwmBFuLNM44Ipux6fN61H1ZeJF3FMbEkm/rGKp5/IfVrO0xrlha6xFvGJjhs9qAuWhe5bhhrceb8U/jfUPw==]]></Encrypt>
</xml>

通過分析,我們得到如下結論:

  • 微信請求授權事件Url時,同樣帶了五個參數,分別爲:Signature,Timestamp,Openid,Encrypt_type,Msg_Signature,應該還有一個微信公衆號的AppId,在請求的Url中
  • 同時還Post了一段需要解密的Xml流文件。

同樣我們需要解密該Xml文件,解密方式同授權通知推送消息解密。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章