使用flask搭建微信公衆號:接收與回覆消息

token驗證的意義

在看了別人的代碼以後對token加密有了些理解了。但又以爲很雞肋。第一次驗證服務器的時候我在那弄了半天的驗證其實不寫也能夠驗證成功,只要直接返回echostr這個字段就好了。微信的服務器只檢查個人服務器返回的值和他想要的值是否同樣,來判斷是否驗證成功,可是驗證的過程是我在本身的服務器上作的,我能夠不驗證,直接返回他想要的值。雖然這樣違背安全的目的。flask

微信這個token驗證應該不僅是第一次驗證服務器時要用,應該是每次接收消息都要驗證是否是從微信服務器發送過來的。第一次是get的請求,接收消息是post的請求。但不管是哪一種,都會是一get的形式和url來訪問。因此哪怕是接收消息,也應該是驗證是不是微信服務器所發送來的。安全

接收和發送消息

經過判斷是get仍是post來分辨是第一次驗證仍是接收的消息。若是時post就解析發送過來的信息的xml(這裏用到了xmltodict這個包,後續學一下)。服務器

xml消息的結構以下:微信

<xml>
<ToUserName><![CDATA[gh_866835093fea]]></ToUserName>
<FromUserName><![CDATA[ogdotwSc_MmEEsJs9-ABZ1QL_4r4]]></FromUserName>
<CreateTime>1478317060</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
<MsgId>6349323426230210995</MsgId>
</xml>

解析post包能夠得到用戶發送過來的消息,而對post包的返回值就是微信公衆號對用戶的回覆,一樣時xml形式。發來的消息有不通的type,能夠採起不一樣的回覆形式等等。app

如下是學習別人代碼後,我寫的代碼。其中對於用戶發送的消息沒有進行token的驗證,只是學習收發消息,沒有寫那麼嚴密。post

from flask import Flask,request
import hashlib
import xmltodict
import time

app = Flask(__name__)

@app.route('/wx', methods=["GET", "POST"])
def getinput():
    if (request.method == "GET"):
    # 表示是第一次接入微信服務器的驗證
        signature=request.args.get('signature')
        timestamp=request.args.get('timestamp')
        nonce=request.args.get('nonce')
        token = "maluguang"
        list = [token, timestamp, nonce]
        list.sort()
        sha1 = hashlib.sha1()
        sha1.update(list[0].encode('utf-8'))
        sha1.update(list[1].encode('utf-8'))
        sha1.update(list[2].encode('utf-8'))
        hashcode = sha1.hexdigest()
        echostr = request.args.get("echostr")
        if hashcode == signature:
            return echostr
        else:
            return ""
    elif request.method == "POST":
        # 表示微信服務器轉發消息過來
        xml_str = request.data
        if not xml_str:
            return""
        # 對xml字符串進行解析
        xml_dict = xmltodict.parse(xml_str)
        xml_dict = xml_dict.get("xml")

        # 提取消息類型
        msg_type = xml_dict.get("MsgType")
        if msg_type == "text":
        # 表示發送的是文本消息
        # 構造返回值,經由微信服務器回覆給用戶的消息內容
            resp_dict = {
                "xml": {
                    "ToUserName": xml_dict.get("FromUserName"),
                    "FromUserName": xml_dict.get("ToUserName"),
                    "CreateTime": int(time.time()),
                    "MsgType": "text",
                    "Content": "you say:" + xml_dict.get("Content")
                }
            }

            # 將字典轉換爲xml字符串
            resp_xml_str = xmltodict.unparse(resp_dict)
            # 返回消息數據給微信服務器
            return resp_xml_str
        else:
            resp_dict = {
                "xml": {
                    "ToUserName": xml_dict.get("FromUserName"),
                    "FromUserName": xml_dict.get("ToUserName"),
                    "CreateTime": int(time.time()),
                    "MsgType": "text",
                    "Content": "Dear I Love you so much"
                }
            }
            resp_xml_str = xmltodict.unparse(resp_dict)
            # 返回消息數據給微信服務器
            return resp_xml_str
if __name__ == '__main__':
    app.run(port='80')

 

參考文章:學習

微信公衆號開發之接收與發送消息加密

相關文章
相關標籤/搜索