在看了別人的代碼以後對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')
參考文章:學習