1.登錄功能
登錄功能通常都是基於 Cookie 來實現的。當用戶登錄成功后,一般會將登錄狀態記錄到 Session 中,或者是給用戶簽發一個 Token,然后瀏覽器將Session 的 ID 或 Token 保存到 Cookie 中,瀏覽器在之后的每次請求中攜帶它們。當服務端收到請求后,通過驗證 Cookie 中的信息來判斷用戶是否登錄 。
2.單點登錄(Single Sign On, SSO)
單點登錄指的是:用戶只需登錄一次,就可訪問同一帳號平台下的多個應用系統。
單點登錄的本質就是在多個應用系統中共享登錄狀態。如果用戶的登錄狀態是記錄在 Session 中的,要實現共享登錄狀態,就要先共享 Session,比如可以將 Session 存到 同一個Redis 中,用戶訪問時,都可以讀取 同一個Redis 的 Session來獲取登錄狀態。
但由於不同的應用系統有着不同的域名,盡管 Session 共享了,但是由於 Session ID 是往往保存在瀏覽器 Cookie 中的,因此無法跨域名傳遞,也就是說當用戶在 app1.com 中登錄后,Session ID 僅在瀏覽器訪問 app1.com 時才會自動在請求頭中攜帶,而當瀏覽器訪問 app2.com 時,Session ID 是不會被帶過去的。
所以實現單點登錄的關鍵就是,如何讓 Session ID(或 Token)在多個域中共享。
實現sessionid或者token多域共享主要有三種方式,父域cookie、認證中心、localstorage
3.實現方式
(1)父域cookie
將 Session ID(或 Token)保存到父域中。也就是將 Cookie 的 domain 屬性設置為主域名,同時將 path 屬性設置為根路徑,這樣所有的子域應用就都可以訪問到這個 Cookie 了。
缺點:不支持跨主域名
(2)認證中心
可以部署一個認證中心,用來專門負責處理登錄請求。
檢查token:用戶訪問某個應用系統,應用系統檢查當前請求有沒有 Token,如果沒有,說明用戶在當前系統未登錄,跳轉至認證中心。認證中心根據 Cookie (認證中心的)判斷用戶是否在其他應用系統已登錄。
返回url:如果發現用戶尚未登錄,則返回登錄頁面,等待用戶登錄,如果發現用戶已登錄,會跳轉回目標 URL ,讓token拼接在目標 URL 的后面,回傳給目標應用系統。
驗證token:應用系統拿到 Token 之后,還需要向認證中心驗證Token ,防止用戶偽造。確認無誤后,應用系統記錄用戶的登錄狀態,並將 Token 寫入 Cookie,然后給本次訪問放行。(注意這個 Cookie 是當前應用系統的,其他應用系統是訪問不到的。)當用戶再次訪問當前應用系統時,就會自動帶上這個 Token,應用系統驗證 Token 發現用戶已登錄,直接返回正常的響應。
(3)localstorage
將 Session ID (或 Token )保存到瀏覽器的 LocalStorage 中,前端通過 iframe+postMessage() 方式,將同一份 Token 寫入到了多個域下的 LocalStorage 中,前端每次在向后端發送請求之前,都會主動從 LocalStorage 中讀取 Token 並在請求中攜帶,這樣就實現了同一份 Token 被多個域所共享。
此種實現方式完全由前端控制,同樣支持跨域。后端需要做的僅僅是在用戶登錄成功后,將 Session ID (或 Token )放在響應體中傳遞給前端。