微信公眾平臺開發(fā)簡要說明 —— 基本原理

這兩個月里,公司的項(xiàng)目基本上都基于微信公眾平臺的開發(fā)上。為了可以快速開發(fā),我使用了 Ruby on Rails框架,而不是之前的 Python,這不是說 Python 不可以做到快速開發(fā),其實(shí)我更多只是想試試新的東西。但效果不錯。

微信公眾平臺的開發(fā),與語言沒什么太大的關(guān)系,大家只要選擇自己熟悉的語言即可,以下我只說明大概的原理,并用 Ruby on Rails 作為代碼示例。

準(zhǔn)備工作

首先,你需要有一個微信公眾號,比如 ”SheldonChen寫字的地方"。在往下繼續(xù)閱讀前,請自覺掏出手機(jī),打開微信掃一掃:

my_wechat_platform.jpg

其次,你需要有一個獨(dú)立域名的網(wǎng)站,用來和微信服務(wù)器交互。

接入公眾平臺

登錄微信公眾平臺后臺后,點(diǎn)“功能”-“高級功能”-“開發(fā)模式”,進(jìn)入開發(fā)模式,如果公眾平臺顯示“尚未成為
開發(fā)者”,就點(diǎn)擊“成為開發(fā)者”:

become_developer.png

同意協(xié)議后,填寫URL和Token:

url_and_token.png

URL是指微信服務(wù)器向哪個URL發(fā)送消息,假設(shè)我們自己的服務(wù)器域名是www.example.com,準(zhǔn)備用/weixin來接收消息,就填寫:

http://www.example.com/weixin

而Token是微信服務(wù)器和我們自己的服務(wù)器通信時驗(yàn)證身份用的,可以隨便填寫,但要注意保密。

然后點(diǎn)“提交”,一般來說會報錯“URL超時”或者“沒有正確返回echostr”,因?yàn)槲覀兊暮笈_還沒有準(zhǔn)備好,所以,第一步是接收微信后臺發(fā)送的驗(yàn)證消息,微信后臺會發(fā)送一個GET請求到上面的URL,并附帶以下參數(shù):

signature,timestamp,nonce,echostr

我們的服務(wù)器在接收到上述參數(shù)后,需要驗(yàn)證signature是否正確,驗(yàn)證方法是先對timestamp、nonce和token先排序,再拼接成一個字符串,計算出sha1,并和signature對比。

注意token不是微信服務(wù)器發(fā)過來的,而是我們自己寫死的一個常量,就是在微信后臺填寫的Token。

如果計算的sha1和微信傳過來的signature相等,說明這個請求確實(shí)是微信后臺發(fā)過來的,如果是別人偽造的請求,由于他不知道token,所以,無法計算出正確的signature。

要防止第三方通過監(jiān)聽發(fā)動replay攻擊,還需要驗(yàn)證timestamp和nonce,這個以后再討論。

如果signature計算無誤,就把微信后臺傳過來的echostr原封不動地傳回去,這樣,就可以通過驗(yàn)證,成為開發(fā)者。

在確保開發(fā)模式打開的情況下,微信后臺會把用戶消息發(fā)到我們的服務(wù)器上,也就是URL:http://www.example.com/weixin

develop_mode.png

微信后臺發(fā)送消息是一個POST請求,但和普通的POST請求不同的是,首先,URL會帶上signature、timestamp、nonce這3個參數(shù):

POST http://www.example.com/weixin?signature=xxx&timestamp=123456&nonce=123

然后,HTTP請求的BODY是一個不規(guī)范的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>

我們自己的服務(wù)器只需要處理該XML,然后,向微信返回一個類似如下的XML:

<xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName>
    <CreateTime>12345678</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[你好]]></Content>
</xml>

就可以完成消息的回復(fù)。微信后臺要求必須在5秒內(nèi)回復(fù),最多重試3次,否則我們自己的回復(fù)消息就到達(dá)不了用戶的手機(jī)了。如果我們自己的服務(wù)器無法在5秒內(nèi)回復(fù),就回復(fù)一個空字符串,告訴微信服務(wù)器,不用重試了,這個消息處理不了,不給用戶回復(fù)了。

上面的交互邏輯看起來很簡單,但實(shí)際上坑有很多。

首先,微信服務(wù)器發(fā)送的POST請求根本就不符合HTTP規(guī)范。原則上POST請求不應(yīng)該在URL上附帶參數(shù),但微信后臺偏偏要這么干,這就讓很多編程語言的標(biāo)準(zhǔn)框架無法獲取到POST參數(shù),因?yàn)闃?biāo)準(zhǔn)的POST參數(shù)是從HTTP BODY中解析的。

所以,從POST獲取URL參數(shù)就需要用到更底層的代碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 微信服務(wù)號開發(fā) 整體流程 域名報備,服務(wù)器搭建 Python開發(fā)環(huán)境和項(xiàng)目的初始化搭建; 微信公眾號注冊及開發(fā)模式...
    飛行員suke閱讀 4,704評論 0 14
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評論 19 139
  • 開發(fā)前首先我們要知道一些概念 各公眾號區(qū)別:1、訂閱號:為媒體和個人提供一種信息傳播方式,主要偏于為用戶傳達(dá)資訊(...
    CoderZS閱讀 3,538評論 1 19
  • 南溪閱讀 182評論 0 3
  • 今天臺風(fēng)“天鴿”登陸。我成了落湯雞。和新認(rèn)識的同路人一起奔跑到馬路對面的的士站。不用任何語言,我們共同感受著雨中奔...
    皮皮琴閱讀 242評論 0 0

友情鏈接更多精彩內(nèi)容