說單點登錄之前,我們必須要搞明白這些事:單點登錄是干啥的? 為啥要用單點登錄。
單點登錄系統-Single Sign On (SSO)是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。它包括可以將這次主要的登錄映射到其他應用中用於同一個用戶的登錄的機制。它是目前比較流行的企業業務整合的解決方案之一。
以前的登錄流程
在系統服務器只有一個的時候,登錄后的客戶信息一般是存在服務器的session域對象中,通過sessionId進行存取或者其他操作。
當用戶通過客戶端訪問我們的系統的時候,用戶通過我們的商城系統首頁輸入用戶登錄信息。然后表現層(controller)去調用我們的業務邏輯層(service)業務邏輯層通過調用持久層(dao)得到的數據從數據庫中取得相應的用戶數據。然后將表現層和持久層的數據進行對比,判斷是否登錄成功。
如果成功,將信息保存在當前服務器的session中,然后將登錄成功的數據返回給客戶。如果登錄失敗,則是直接將失敗信息返回給客戶。
而在訪問的時候,用戶通過sessionId沖session中獲取用戶的商品詳情。流程如圖:
集群登錄分析
之前的登錄方式,在服務器只有一台的時候,是沒有問題的。但是,每個服務器可以承受的訪問量是有限制的。這個時候,我們就需要用多個服務器撘一個集群,共同為我們的商城提供服務。
那么問題來了。這么多台服務器同時提供服務,很有可能用戶第一個請求發送到了服務器1,第二個請求就發送到了服務器2。請求具體會分配到哪個服務器是隨機的。這時就會涉及這么個問題:如果登錄的請求發送到了第一個服務器上,那么,用戶的登錄信息就會存在第一個服務器的session上。第二個請求,假如說是用戶在下單的話,帶着的那個sessionId從服務器2中就沒有辦法找到我們的session信息。那么,經過業務邏輯層判斷時,就會判定,該用戶是沒有登錄的,讓用戶再次重新登錄。如圖所示:
對此,我們有兩個解決方案:方案一,如果搭建的集群中服務器並不多的話,就將服務器中的session進行共享。服務器會在局域網內進行廣播,這個時候,如果局域網內中的服務器過多的話,服務器需要拿出很多的資源用來做session的同步。這樣的話,集群數量的增多反而會降低集群整體處理請求的效率。所以,該方案適用於服務器低於5台以下的集群。
方案二:不再將用戶的信息放在session中。而是將session信息放在系統的redis緩存中。由redis實現session的相應的功能。使用redis實現session的功能的原理圖如下:
(兩個redis其實是一個數據庫,這里這樣畫室為了簡潔)
當用戶登錄的時候,依然是輸入用戶名和密碼。然后表現層將數據將數據傳入單點登錄系統,由單點登錄系統從數據庫中將數據取出,然后判斷用戶是否登錄成功。如果登錄成功,生成一個類似於sessionId的東西,我們稱之為ticket。然后以ticket為redis的鍵,用戶的數據作為值。存入redis服務器,並且將登錄成功的信息和ticket一起返回給用戶的瀏覽器,將這個信息寫入用戶的cookie。
用戶在訪問的時候,先根據用戶的ticket信息從redis服務器中查詢用戶的信息,如果查詢到,則跳轉到服務器,為用戶提供服務,如果用戶沒有登錄,則直接跳轉到登錄界面。
注:圖片均取自其他老師,非本人自己畫的。