1. 程式人生 > >使用Python開發微信公眾號

使用Python開發微信公眾號

微信公眾號是開發者或商家在微信公眾平臺上申請的應用賬號.

在接入自己開發的微信公眾號伺服器時,需要提供UrlToken訊息加密金鑰:

  • Url 是微信公眾號接收微信系統推送的地址(只支援80埠)
  • Token 用來驗證安全性(接入時微信系統會向URL傳送GET請求驗證)
  • 訊息加密金鑰 用作訊息體加密金鑰

接入微信公眾平臺時,微信系統會發送GET請求對伺服器進行驗證.該請求攜帶signature、 
timestampnonceechostr四個引數(具體意義參見官方文件).加密流程如下:

<code class="hljs livecodeserver has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.</span>將<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">token</span>、timestamp、nonce三個引數進行字典序排序
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.</span>將三個引數字串拼接成一個字串進行sha1加密
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3.</span>開發者獲得加密後的字串可與signature對比,標識該請求來源於微信</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

微信官方提供了PHP的實現,Python版本的實現如下:

<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">sign</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(data)</span>:</span>
    arr = [weChat[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'token'</span>], data[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'timestamp'</span>], data[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'nonce'</span>]]
    arr = sorted(arr)
    tempStr = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">''</span>.join(arr)
    data = tempStr.encode(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'UTF-8'</span>)
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> sha1(data).hexdigest()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

以上程式碼使用Token對資料進行加密,返回加密後的結果.在獲取到signature欄位後比較是否相同,若相同則原樣返回echostr欄位,否則返回異常或其它結果.

校驗成功後,微信公眾號收到訊息或其它事件推送將會把資料使用POST請求傳送到配置的URL上,可根據微信官方文件進行後續開發.