前言
分布式用戶認證, 有個簡單的稱謂就是單點登陸, 即一處登陸,到處通行.
說詳細一點就是,集中的用戶統一身份認證和分布的式的用戶驗證和資源訪問控制.
對于小公司而言,提供的服務少,常常用戶認證和服務混合在一起,體會不到分布式用戶認證好處.
隨著公司規模的擴大,提供的服務越來越多,把用戶認證和服務提供拆分開來,實現分布式用戶認證,可降低系統的相互依賴性,提高系統的可擴展性.
常見的方案
基于普通token的方案.
這個方案通常在用戶登錄后,把用戶信息儲存與中心服務器, 同時給客戶端一個普通token, 以后訪問服務時均以此token識別用戶身份. 這個token只是一個hash值,一個唯一的ID,自身不含用戶信息,要辨別token的真偽,需要的中心服務器查詢,這是一個集中用戶認證的方案,簡單易用,當可擴展性不高.
本文介紹一個新的方案
基于JSON Web Token(JWT)的方案.
JWT,簡單的說就是把用戶的公開信息和信息的簽名合成一個字符串,保證信息無法偽造.詳細可參考互聯網上的資料。
JWT 和基于hash值的普通token的主要不同點:
- JWT 自身包含用戶的公開信息。
- JWT 不用到中心服務器查詢就可驗證真偽。
這些特點,使得JWT 很像現實生活中的身份證,簽證等證件。
這個方案,通過用戶登陸后,中心服務器給客戶端一個JWT,這個JWT包含用戶的公開信息,還有用戶權限等信息。之后,客戶端訪問服務時,就以這個JWT作為身份識別,而服務提供者,不用到中心服務器查詢,自己可校驗這個JWT的真偽。
以示范案例說明
以一個社區應用例,功能模塊如下:
- 發帖討論的論壇模塊
- 實時通信模塊
- 收費的教育視頻模塊
- 收費的音樂模塊
當然,以上四部分都需要用戶認證。
這四個模塊,通常由四個項目組完成。
作為架構設計者,有兩個重要的思想:
- 假設這四個模塊,分別由四個獨立的公司來開發。
- 每個模塊不只我們公司用,其他公司也可用
就是把API或是服務service 當做最終獨立的產品來設計,這樣就能設計出好的架構.
對于這個系統,我們看看用戶認證系統如何設計?
拋開傳統的登陸概念,傳統的登陸通常只是登陸一個地方,訪問一種服務.
當設計認證系統時,不要想我們在設計軟件系統,就當在設計一個國家,沒錯一個虛擬的國家.
看看國家的分布式用戶認證是怎么運作的?
以美國為例,移民局負責頒發用戶簽證,而里面的大學,酒店,企業就是各種服務提供者.
這里用戶認證和服務提供是分開的.
要入境美國,首先得像移民局申請簽證.
當用戶拿著簽證去住酒店時,酒店服務員會查看簽證的真偽及有效期.
當用戶拿著簽證去住企業應聘時,企業會查看簽證的真偽及有效期,還有就是權限,如果是旅游簽證,對不起,旅游簽證不能打工.
注意:簽證是由移民局集中發行的,而校驗確是分布的.
酒店服務員驗證簽證時,不會打電話到移民局查詢真偽.
我們的用戶認證系統,其實只要把這一套機制幫過來即可.
由統一的用戶認證系統負責頒發簽證,而用戶訪問各種服務時,持有這個簽證就可以了.
用戶認證后,我們可以把用戶的公開信息如user id等,還有就是授權信息,比如6個月的視頻教程授權,1個月的音樂授權等寫到這個簽證上,這樣用戶就可訪問各種服務.
JWT 防偽有兩類簽名機制,一類是基于secretKey的Hash機制,一類是非對稱簽名機制.
第一類Hash機制,JWT的創建和驗證使用同一個秘鑰,僅適合公司內部用.對應開放平臺,要開放給其他公司使用,需要采用非對稱簽名機制,這樣創建和校驗是兩個秘鑰,保證token的集中發行.
分布式JWT用戶驗證的問題.
分布式JWT用戶驗證的問題的一個問題是,Token 一旦發行,無法注銷,只能等其自行失效.
這個不單是JWT的問題,所有可分布式驗證的證件都有這個問題,包括身份證,簽證,駕照等.
駕照丟了,去管理局注銷,但這個注銷,不會讓丟失的駕照立即失效,除非駕照的驗證是集中式的.
這也是為什么幾乎所有的證件都有一個有效期的原因.
對應JWT,為了保證安全,我們可以使用一個比較短的有效期,同時采用一種以舊換新的機制,確保安全.
這個機制有點類似生活中的駕照年審或者簽證延期,即每隔一段時間做一次審查并核發新證,由于不需要人工操作,我們的這個審查頻率提高一些.
Token以舊換新的機制,請參看:
http://www.lxweimin.com/p/b4cf771e570e
注:現實生活中,護照和簽證有些差別,對于軟件系統這個差別就不考慮了,統一當成證明身份的證件.