《微信小程序七日談》系列文章:html
本系列的文章並不是初學教程,而是筆者在具體開發過程當中遇到的問題以及部分解決方案。算法
前幾篇文章的內容主要集中於小程序開發框架中的一些機制細節,基本上都是客戶端層面的知識。隨着小程序項目的不斷深刻,咱們不得不面對一些須要客戶端與服務端協同完成的需求,好比用戶登陸功能。小程序
大多數的小程序都會有自身的用戶體系,然而小程序必需要通過微信帳戶的驗證受權,而後再與第三方服務器(也就是公司本身的服務器)通訊實現用戶的登陸。這裏面就涉及到微信帳戶信息與自身用戶信息的耦合。下面就簡單介紹一下咱們項目目前實現用戶登陸的技術細節。微信小程序
在制定具體實現方案以前,咱們首先思考一下用戶登陸功能須要注意哪些細節。一般來說,實現用戶登陸功能須要注意如下兩點:api
登陸狀態保存就是登陸成功後請求站內數據接口時無需再次登陸,客戶端與服務器按照既定的規則進行用戶有效性驗證。瀏覽器環境下的登陸狀態保存一般使用cookie實現,這種方案的實現原理是瀏覽器發出的http請求header中會攜帶客戶端的cookie。以下圖:
瀏覽器
安全驗證是爲了應對流量劫持,防止中間人攻擊,在咱們的頁面中插入亂七八糟的內容。你們可能會想到使用https來防止流量劫持。https能夠應對絕大部分的應用場景,有效的防止流量劫持。但其實市場上有一些「黑科技」軟件能夠捕獲而且解密https加密信息的,好比Fiddler。因此在https的基礎上,再進行一層安全驗證是還有必要的。安全
你們能夠參考這篇文章瞭解fiddler解密https的知識。服務器
自定義安全驗證一般的方案是客戶端與服務器約定好一個驗證簽名,客戶端在發出http請求以前按照約定好的算法計算出一個簽名字符串,而且在http請求中將計算簽名的參數傳遞給服務器。服務器接收到請求以後,解析出簽名字符串和客戶端傳遞的計算參數,而後按照一樣的算法計算出簽名字符串,並將其與客戶端的簽名進行對比,徹底一致則驗證經過,不然返回驗證未經過的數據。以下圖:
微信
上述流程成立的前提條件是:cookie
那麼這套方案在小程序平臺上是否能夠複用呢?答案是否認的。
目前咱們所知的小程序存在如下限制:
可是咱們在吐槽小程序重重限制的同時獲得了一個好消息:http請求能夠自定義header。咱們彷彿看到了解決問題的銀彈。
登陸識別信息在沒法使用cookie傳遞的限制下只有兩種傳輸途徑:
小程序提供了獲取設備信息的API,提供了在客戶端計算簽名字符串的參數。按前文提到的驗證規則,客戶端計算簽名的參數必須傳遞給服務器才能保證兩端計算的一致性。因此咱們又面臨了以前的抉擇,是query仍是header?
其實使用任何一種途徑均可以完成需求,可是url query(一般稱爲data
)的語義應該是與接口功能緊密相關的數據,而且http請求的header比url query數據更保密,因此咱們團隊最終採用header傳遞登陸識別信息和設備信息的方案。
肯定信息的傳遞方式只是第一步,在小程序平臺下實現本身的用戶登陸仍然有不少細節須要琢磨。咱們首先看一下官方文檔給出的第三方登陸流程圖:
官方文檔給出的流程是實現第三方登陸的基本流程,可是具體的登陸功能中仍然有一些細節上的不一樣,好比:
3rd_session
和openId
不能明文暴露給客戶端,須要進行加密;在小程序登陸機制的基礎上,咱們團隊在制定安全登陸功能時最終採用了以下方案:
對比微信官方的登陸流程圖,有如下幾個細節:
3rd_session
和openId
不直接暴露給客戶端,而是經過可逆的加密算法進行加密後,組合成token
暴露給客戶端;3rd_session
和openId
而且加密後返回客戶端,以便後續請求使用;token
獲取3rd_session
和openId
,而後與uid結合從新計算token。最後將uid和token一併返回給客戶端。用戶登陸成功後,客戶端將uid和token儲存在本地,以便後續請求數據接口使用。
客戶端儲存token和uid的方式能夠採用storage或者
app.globalData
。
數據接口是在用戶登陸成功以後才能夠進行請求,相比較登陸功能,數據接口的請求驗證方案要簡單不少。以下圖:
接口請求只需驗證sign以及token便可,若是token錯誤或者已過時,則返回客戶端從新登陸的標識。
想在微信小程序中實現本身的用戶體系須要花費一些力氣,每一個公司都有自身的用戶登陸驗證體系,同時還要考慮安全性和狀態保存問題。在小程序不支持cookie、http請求header不攜帶設備信息等限制下,實現登陸功能的各類細節都須要採用一些折中的手段。並且每每這些方案顯得有些臃腫而且難以維護,很是考驗開發者的抽象能力。
本篇文章闡述的是筆者團隊目前採用的登陸實現方案,並不是最佳實踐,許多細節仍需打磨。但願能夠給你們一些參考。