鑑於微博,QQ,微信等開發平臺的影響,互聯網界的工程師都知道OAuth協議,對Token 存儲用戶信息的機制有所瞭解,卻不多有人說起兩方OAuth這個概念。前端
說到OAuth協議,潛意識裏都會想到涉及認證,客戶,和服務器,進而是認證服務器,客戶端應用和資源服務器三方。redis
如今通用的OAuth協議是OAuth2.0,是一個互聯網開放受權協議,用於規範資源服務器,客戶端應用,受權服務器三者的職責,實現客戶端應用在不直接獲取到普通用戶的用戶名和密碼的前提下,訪問用戶的私有資源。算法
在實際應用開發過程當中,咱們的應用複雜性沒有達到必定規模時,應用程序只涉及到客戶端APP和服務器端中心雲服務的認證和業務處理。咱們能夠對OAuth2.0協議進行簡化,演變爲兩方OAuth。數據庫
上圖[Auth-history.png]是幾個服務器客戶端驗證的階段。後端
OAuth 協議更多的能夠理解爲是一個寬泛的協議,在工程應用方面只關注規範,不要求細節。
最初的OAuth協議是服務器根據HTTP 協議頭的Authorization 字段驗證客戶端身份。而現在逐漸演變成使用Token 的方式標記客戶端身份,存儲用戶狀態信息,至於Token如何生成,在HTTP 協議中如何傳輸,並無過多硬性要求。安全
在OAuth協議體系中,消費者是指開發者開發的APP,這裏的APP 更是一個廣義的概念,不侷限在安卓和iOS應用這兩種類型。PC網站,移動端WebView也被認爲是APP 服務器
服務端,各類雲平臺如何識別這些應用,藉助於應用編號和應用密鑰機制,應用編號就是APP_ID,或者APP_KEY,用於惟一識別應用。密鑰就是APP_SERCRET,用於請求籤名等安全算法的入參,和服務器端驗證的憑據。微信
APP_KEY和APP_SERCRET的分配和管理是實現兩方OAuth的第一步
讀到這裏,或許你有疑問了,上文說到的不一樣APP,無非是安卓,iOS,WebView,咱們何不定義不一樣的枚舉來標明不一樣的客戶端,甚至可使用User-Agent判斷。網絡
1 PC,2 安卓 3 iOS 4 微信
這樣的分類能夠解決嗎,答案是很難。架構
實際上這是兩個概念,從操做系統的角度劃分更多的是一種數據來源渠道的概念,而APP_KEY的本質屬性是接入雲端平臺的開發者應用標記。
如下是一個簡版的Token生命週期模型
Token由客戶端發起,服務器雲端負責分配,典型的場景,在用戶登陸成功後分配,必定有效期內過時,支持每次請求不一致,token滑動過時機制。默認30分鐘失效。
用戶標記key: userid+應用編號。md5(userid+鹽鑰+時間戳) 鹽值固定。生成規則能夠根據項目個性化調整,Token值不可逆。
服務器端 key value形式存儲到redis中,key爲token,value爲加密值
客戶端 Token,按需存儲在本地,後續接口調用時使用
過時時間內失效,如初始分配60分鐘,那60分鐘後自動生效。
退出時,須要調用接口,刪除Token。
這裏會引出一個思考
退出功能須要網絡支持嗎?
這個問題的原因是我發現有些工程師,退出功能是這麼作的,頁面跳轉,清除本地Token。
Token表明的是用戶狀態,這種狀態表明的是客戶端與服務端的一種關聯關係,退出功能是切斷這種關聯。
HTTP 是無狀態的,單純的作請求響應,而業務必須是有狀態的,不然業務沒法流轉和推動,這種狀態交給Token負責,兩者是如何關聯的。是Token設計中須要考量的。
一個相對完整的Token落地機制是實現兩方OAuth的第二步
簽名(Sign)用於保證數據的真實性和完整性,從時效,合法性,頻率幾個維度處理。
對全部待簽名參數按照字段名的ASCII碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這裏須要注意的是全部參數名均爲小寫字符,最後加&secret=app_secret; 對string1做簽名算法,字段名和字段值都採用原始值不進行URL轉義。具體簽名算法爲sign = md5(string)。
除登陸外全部接口,由服務端決定開啓或者關閉簽名驗證。業界叫驗籤。
簽名就用到了APP_SECRET
採用先後端分離,將接口參數分爲系統級別參數和業務級別參數。
系統級參數主要包括app_key,timestamp,token,os_type,sign,主要置於HTTP 請求頭位置。
業務參數基於業務需求,採用POST 或者GET方法按需傳遞。
經過客戶端時間戳timestamp,來肯定真正的客戶端發起時間。
服務器端檢測時間差,客戶端請求時間與服務器時間的差值與超時時間作對比。例如,咱們能夠約定時間差大於5分鐘間隔的請求爲無效請求,或者超時請求。
使用App-Key的方式識別應用終端,企業內部不一樣的應用,由雲端服務統一管理。
場景1
進行個性化配置 ,來自於微信公衆號的登陸用戶的過時時長設置爲一天,而來自於PC官網的用戶的登陸過時時長設置爲一週。
場景2
公司某個產品線的普通版和定製版的區分,使用App-Key,對功能的簡易複雜度,收費模式作梯度設置。
場景3
應用於SASS應用識別,多租戶數據隔離,在數據庫對應用數據作隔離。進而爲相關的運營數據分析提供支持。
1 後臺配置關閉啓用開關,開發階段能夠關閉驗證,建議開啓。
2 啓用驗證後,前端須要有公共方法計算請求籤名。後臺須要增長安全驗證模塊驗證請求合法性,負責登陸過時失效檢測,參數完整性和權限驗證。
3 安全方面關注安全彈性,安全驗證級別經過timestamp, sign, token參數,三個維度配合,逐層升級。經過增長驗證條件和複雜性加強安全級別。安全級別作到合理便可,沒有一律而論。
以上給出了一套基於兩方OAuth方式的雲端,客戶端服務設計模型。在應用服務不復雜,業務場景容許的前提下,使用兩個OAuth方式,伴隨着業務發展,能夠逐步演化爲基於三方身份的OAuth協議工程實現。
Token機制和簽名機制也能夠 獨立分層,與業務應用分離,演化爲網關係統。
這樣的設計符合架構領域的簡單,演化原則,是一種很實惠的應用架構方案。