您的位置:首頁>正文

微信卡卷是怎麼搞的?掙點零花錢!用Flask教你如何開發微信卡卷

說明

這個專案實際開發時間為1.5天, 其中被微信文檔坑掉的時間大概占到了三分之二, 所以說經驗很重要。 博主之前做過比較多基於微信的項目, 在微信授權和jssdk應用上面還是比較熟悉的, 這個項目的功能非常簡單:

微信授權獲取使用者資訊保存到資料庫, 保存成功之後調用微信的jssdk喚起微信的卡券領取頁面, 使用者領取成功之後更新資料庫記錄標示已領取。

Flask裡面對Mysql資料庫操作用的是Flask-Mysql,

當然也可以使用Python-Mysql, 這個取決於個人需要, 使用方法都差不多, 總結一下用到的庫, 大概就是下面這些了

項目比較小, query和insert夠用了, insert也可用於update。 關於項目的完整代碼就不貼出來了, 也沒啥用, 下面就說一些關鍵點吧。

首先用戶進入首頁, 會進行微信的授權, 代碼如下

微信的授權是分步驟進行的, 上面的代碼是獲取一個code, 有了這個code才能去拿token, 上面代碼中需要注意的是 redirect_uri 這個變數一定要進行url編碼, 否則微信會報異常, csrf_state 變數是生成一個隨機字串, 用於防止csrf跨站攻擊, 微信文章說不加也可以,

為了安全期間, 咱們還是加上去吧, 誰叫咱們是搞安全的呢。 這個csrf_state會在獲取到code後微信重定向回來時帶在url後面, 所以下一步是可以拿到這個參數的。 session["csfr_token"] = csrf_state 這個就很簡單的, 把這個隨機字串寫入到session, 這樣在下一步操作的時候會去檢查進行比對。

這裡我要說明一下為何需要這個 csrf_state 參數, 微信授權在獲取code的時候, 請求是通過前端的URL進行跳轉, url跳轉很明顯的一個問題就是明文傳輸, 明文傳輸的時候arp攻擊是很容易拿到請求連結的, 如果說我們實現已經在伺服器上的session裡面存儲了那個隨機字串, 微信回檔回來的時候伺服器拿到參數進行比對, 如果這個參數值跟session裡面的一致, 則認為是正常的請求, 否則這個請求就是偽造的, 比如典型的請求重放攻擊,

在這裡就用不了了, 就算被arp拿到了連結, 發過去伺服器也會認為請求非法所以我還是建議加上這個參數。

Flask跳轉使用redirect方法。

下面是關鍵的授權部分, 獲取授權Token的回檔連結在上一步已經給出, 微信會自動回檔到這個頁面, 相關注釋我直接在代碼裡面寫了

代碼裡面涉及到的兩個單獨方法如下,第一個獲取基礎access_token

第二個單獨方法是獲取ticket,請求的方式一樣,唯獨參數值不一樣

這兩個方法獲取回來的資料都需要進行緩存。

前端頁面在載入的時候需要初始化微信分享和卡券的相關簽名參數等,所以需要把前面生成的簽名數據傳過去,通過render就可以輕鬆傳到前端,render這個東西不要覺得有多神秘,搞過nodejs和thinkphp的估計也都見過,如下代碼

return render_template("index.html", status=page_status, jssdk=jssdk_data, cardId=card_id, cardExt=card_data)

在自己安卓手機上測試通過,發給客戶,客戶一直說他的手機不行,提示簽名錯誤,我就鬱悶了,我這裡測試很多遍都可以啊,要求客戶發截圖,截圖發來看看確實簽名錯誤,神奇了。仔細一看,客戶用的是IPhone,難道是安卓可以ios不行,經過長達4個小時的不斷嘗試,終於給解決問題了,開啟微信jssdk的調試模式後在安卓和ios上都會彈窗提示普通jssdk的簽名正確,安卓上面領取優惠券成功後會顯示優惠券相關資訊,仔細一看發現雙引號被轉義各種斜杠,但是是成功的,然而iphone不行,此時我才想起這個坑我之前就遇到過,因為ios解析json的時候認為{}裡面的是一個json物件,會把一些字元轉義,導致簽名字串不一致,所以簽名錯誤,而安卓則認為{}是一個字串,正常的處理,就不會報錯。

於是就有了上面那個

var cardExtString = '{"timestamp":"[[ cardExt.timestamp ]]","nonce_str":"[[ cardExt.nonce_str ]]","signature":"[[ cardExt.signature ]]"}';

直接定義成一個字串,這樣安卓和ios識別就會一致的認為這個變數為字串類型,不會做特殊處理,至此BUG解決。

這裡順便說下axios,使用方法如下代碼

後記

遇到問題多穀歌,經驗真的很重要啊!!!

關於專案代碼或者對微信相關功能開發的問題,可以發到我郵箱。

著作權歸作者所有,如有侵權請聯繫小編刪除!

代碼裡面涉及到的兩個單獨方法如下,第一個獲取基礎access_token

第二個單獨方法是獲取ticket,請求的方式一樣,唯獨參數值不一樣

這兩個方法獲取回來的資料都需要進行緩存。

前端頁面在載入的時候需要初始化微信分享和卡券的相關簽名參數等,所以需要把前面生成的簽名數據傳過去,通過render就可以輕鬆傳到前端,render這個東西不要覺得有多神秘,搞過nodejs和thinkphp的估計也都見過,如下代碼

return render_template("index.html", status=page_status, jssdk=jssdk_data, cardId=card_id, cardExt=card_data)

在自己安卓手機上測試通過,發給客戶,客戶一直說他的手機不行,提示簽名錯誤,我就鬱悶了,我這裡測試很多遍都可以啊,要求客戶發截圖,截圖發來看看確實簽名錯誤,神奇了。仔細一看,客戶用的是IPhone,難道是安卓可以ios不行,經過長達4個小時的不斷嘗試,終於給解決問題了,開啟微信jssdk的調試模式後在安卓和ios上都會彈窗提示普通jssdk的簽名正確,安卓上面領取優惠券成功後會顯示優惠券相關資訊,仔細一看發現雙引號被轉義各種斜杠,但是是成功的,然而iphone不行,此時我才想起這個坑我之前就遇到過,因為ios解析json的時候認為{}裡面的是一個json物件,會把一些字元轉義,導致簽名字串不一致,所以簽名錯誤,而安卓則認為{}是一個字串,正常的處理,就不會報錯。

於是就有了上面那個

var cardExtString = '{"timestamp":"[[ cardExt.timestamp ]]","nonce_str":"[[ cardExt.nonce_str ]]","signature":"[[ cardExt.signature ]]"}';

直接定義成一個字串,這樣安卓和ios識別就會一致的認為這個變數為字串類型,不會做特殊處理,至此BUG解決。

這裡順便說下axios,使用方法如下代碼

後記

遇到問題多穀歌,經驗真的很重要啊!!!

關於專案代碼或者對微信相關功能開發的問題,可以發到我郵箱。

著作權歸作者所有,如有侵權請聯繫小編刪除!

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示