多平台的網站實現單點登錄系統(SSO)的開發思路 讓你的會員中心更加統一(參考資料)


單點登錄並不是一個新鮮的玩意兒,比較官方的解釋是企業業務整合的解決方案之一,通俗來講SSO就是一個通用的用戶中心,國內比較流行的UCenter就是一套單點登錄解決方案。而近期以CSDN明文存儲用戶密碼並泄露用戶信息開始的各大網站爭先恐后的泄露自己的用戶數據庫除了暴露了這些網站的良心和智商外,如何設計用戶中心已成為架構師們的熱點話題之一。在最近一兩年的項目經驗中有幸接觸到各種平台的單點登錄系統的開發,所以借此機會總結下B/S架構的單點登錄系統的開發經驗。

單點登錄系統的類別

就目前比較流行的應用來看,單點登錄系統主要分為三種類型:一種是基於oauth協議的網絡令牌(我是這么叫的),一種是基於Web Service或者簡單Http協議實現的Passport機制,還有一種是以openid框架形成的通用賬號登錄機制。其中,基於oauth協議主要應用在網站外部,比較知名的有Google Account、Facebook Connect和新浪微博鏈接等;Passport的應用主要是針對同一網站內不同架構不同平台,知名產品則更是數不勝數,例如Google Account賬號基本上可以應用全部Google的網站,而國內各大門戶無數的應用系統也都只需要一個用戶通行證就能暢通無阻;至於OpenID這樣會共享用戶信息的應用,在國外可能會很火,在國內這樣一個用戶一寸金的利益集團面前可能會被采納,所以下面的論述也主要針對前面兩種。

單點登錄系統的優點

對於用戶來講,最理想的情況下一個賬號和密碼就可以橫行整個互聯網,當然這是不可能的。不過現實中稍微有點價值的網站基本上都可以支持各種oauth協議的單點登錄系統,所以能使用微博賬號、SNS賬號或者豆瓣賬號登陸的將會為用戶帶來更多的方便。

對於企業來講,尤其是業務繁瑣復雜的大企業,單點登錄系統可以讓他們不必為每一個應用都開發用戶系統,從而大大降低了工作量,而且統一的用戶數據在后期管理和維護中也會更加方便。而基於oauth協議的單點登錄系統雖然開發成本高昂,但是能為企業帶來最具有價值的第一手用戶信息,其收益可觀。

單點登錄系統的基本流程

單點登錄系統(SSO)功能流程圖

如上圖所示,不管是哪種方式的SSO系統其功能流程大概都是這樣:應用系統只需要調用SSO的驗證接口驗證當前用戶是否為已登錄用戶,如果是未登錄用戶或者嚴重不合法則跳轉到SSO系統。此時已注冊用戶可以直在SSO成功登錄后返回應用系統,應用系統開始重復上述步驟;而未注冊用戶則需要先注冊或者使用第三方SSO初始化賬號,繼而重復上述步驟。

不同的是,賬號鏈接這樣的SSO系統在登陸成功后返回給應用系統一個key值、用戶uid和其他信息,而應用系統一般還是需要在自己的用戶系統中新建一個用戶賬戶並且建立一個映射關系來關聯SSO系統的返回值。如下圖所示是實現綁定微博賬號登陸的數據庫模型圖,其中應App_Users表可以實現一個用戶綁定多個單點登錄賬號,並且這樣的用戶是不需要再應用系統中存儲密碼等不必要的信息的。而Passport機制的SSO系統基本上處理所有用戶登錄、注冊、驗證的行為,其他應用系統只需要按需取用即可。

微博登錄功能的數據庫模型

單點登錄系統開發難點

從上述功能流程可以看出,使用基於oauth協議的單點登錄系統應該是比較好的解決方案,但是沒有誰願意把用戶的掌控權拱手讓給別人,所以國內很多中小網站就算是沒有能力開發自己的passport單點登錄系統,也會去選擇UCenter這樣第三方開源的單點登錄系統。而Passport機制的單點登錄系統都會面臨這么一個問題,如何跨域傳遞cookies,至於為什么使用cookies、為什么要跨域這么啰嗦的廢話我就不多寫了,常用的跨域傳遞cookies的方法有三種:javascript/iframe、header和借助數據庫。

javascript/iframe的思路是將單點登錄種下的cookie動態傳到應用系統,在ajax/jquery廣泛應用的時代javascript的是很常見的解決方案,例如UCenter的做法就是在單點登錄系統登陸后使用一段javascript動態把cookie傳遞到所有設置為同步登錄的應用,而iframe因為存在諸多弊端不建議使用。

header的解決方法是使用P3P機制進行跨域傳輸,但是IE必須用加P3P的頭信息才可以跨域。看來IE對跨域的限制更為嚴格!所以要想實現完全跨域,在header頭里面加上這一句話最好:header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA div COM NAV OTC NOI DSP COR"');。不過在以前使用P3P協議開發單點登錄系統的時候或多或少都有些莫名其妙的問題,看來還是掌握的太少了。

數據庫存儲,還是以Ucenter為例,在Discuz的cdb_sessions表就是一個結合session實現的跨域傳遞session的功能,只不過這樣的功能會給數據庫帶來嚴重的I/O負擔,但凡有點流量再碰上點極品的用戶這樣的數據庫性能肯定要被嚴重拖累。

在我實際開發過程中,一般這樣解決單點登錄系統的跨域傳遞cookie問題:首先驗證用戶來源是否在我們的站點列表內(如果是首先進入SSO則略去這一步),其次驗證用戶合法性,用戶通過驗證后,加密cookie和公用密鑰后的值將會在用戶登錄之后作為參數一起跳轉回來來源的應用系統,應用系統獲取到cookie值后調用SSO接口進行解密、驗證等工作。此外,還有一種比較簡略的SSO設計方案,所有SSO系統應有的功能都以API形式呈現,接受被授權的應用系統的請求並且返回相應的XML或者Json結果,不同的是,這樣做需要應用系統最起碼的有自己的登陸和注冊頁面,適用於同步不得不使用自己用戶功能的已經成型的外部應用系統。

此外,在上一篇文章中討論過的用戶密碼加密問題,由上圖也可以看出,pass字段存儲的應該是用戶真正的密碼經過md5和加上salt值(隨機字符串)再次md5,也就是md5(md5(realpass).salt),這個是程序猿應該知道的最基礎的加密方式。此外,很多人容易忽略的一個地方是cookie校驗,至少我親身體驗了京東修改完用戶密碼以前種下的cookie依然可以使用,Firebug看了下京東存儲的Cookie雖然是加密的,但是明顯的驗證cookie只是驗證了cookie是否為空或者是否可以解密,而完全沒有去驗證cookie用戶是否合法,這樣如果知道了京東的加密算法,即便是不知道用戶密碼,也可以偽造用戶cookie進入用戶賬戶。

至於網上很多企業給出的SSO解決方案,我就不噴了,MD,如果真要用,UCenter或者簡單的使用新浪、騰訊、豆瓣的網站鏈接都不錯,雖然UCenter問題很多(這個以后再噴),但是最起碼的企業對用戶具有完全的掌控權。

http://www.itokit.com/2012/0523/74123.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM