SSO英文全稱Single Sign On,單點登陸。當咱們搜索單點登陸
的時候,會發現不少的文章,然而這些文章通常都是基於一種通用的場景描述,一般在各自的業務環境會更加複雜。在本篇文章,我將描述具體場景下實現單點登陸的方案。html
SSO英文全稱Single Sign On,單點登陸。SSO是在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統。它包括能夠將此次主要的登陸映射到其餘應用中用於同一個用戶的登陸的機制。它是目前比較流行的企業業務整合的解決方案之一。前端
企業發展初期,通常一個域名站點即可承載獨立業務。但隨企業對於新業務的探索,便都會申請一個新的域名用於這部分新業務的功能承載,一方面是爲了作區分,另外一方面是知足監管的要求。而且須要在這種模式下打通原先站點的用戶體系。新的獨立域名主要有兩種:webpack
對於第一種場景,通常咱們採用共享session
的方式就能夠作到用戶在不一樣域名之間跳轉而無需重複登陸。具體實現主要是將cookies
中關於用戶登陸態的sessionid
的domain設置爲.a.com
。web
這種場景較爲簡單,實現上作好新老模式之間的切換便可。由於默認狀況下sessionId的domian是www.a.com
,若是以前已經訪問過www.a.com站點,且登陸的時候未清除掉domian爲www.a.com
的sessionid,那麼訪問www.a.com
的站點,瀏覽器會把兩個同名sessionId傳遞到服務端,因爲是key-value
的形式,服務端沒法分辨哪一個是新的,哪一個是舊的,若是取了舊的,那麼就沒法獲取用戶此時登陸狀態。解決這個問題,只須要在設置sessionId的時候把原有domian爲www.a.com
的置爲過時,或者用一個新的sessionId鍵便可。具體查看set-cookies介紹。redis
這種場景在咱們的移動站點用的比較多。例如主站www.a.com,移動站點爲m.a.com這種場景。npm
#設置domian爲.a.com的sessionId
Set-Cookie: sessionId=a3fWa; Domain=.a.com; Secure; HttpOnly
#將domian爲www.a.com的sessionId置爲過時
Set-Cookie: sessionId=a3fWa; Domain=www.a.com; expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; HttpOnly
複製代碼
接下來咱們主要描述第二種場景。對於這種場景,主要要求是用戶無感知,須要作到如下幾點:跨域
以上是主動同步登陸態的時序圖。圖示中的ticket主要存放在redis
中,你也能夠存放在其餘的存儲媒介甚至應用運行內存,可是須要注意的一點就是ticket應一次有效,用過以後須要清除掉。因爲這裏咱們的b站點也在本身的受控範圍,而且redis的讀寫性能也至關優越,因此a和b鏈接並讀取了同個redis。若是b站點不在受控範圍內,可在b站點後臺發起一個請求到a站點詢問ticket的有效狀態。具體流程以下:瀏覽器
因爲a、b站點相互獨立,假設各自的session過時時間爲半小時,若是a站點一直處於訪問狀態,那麼session會一直續命下去,可是b站點因爲超過30分鐘沒有訪問,session狀態已通過期,這時候訪問b站點就會有這個場景了。具體流程以下:安全
同流程二,這個場景的出現也是由於長時間未訪問登陸b站點致使,與流程二不一樣的是,這個場景是302直接跳轉同步頁面的方式,由後臺直接判斷,適合後臺直出頁面,若是是純靜態頁面請使用流程二,具體流程以下:bash
以上流程主要在於實現SSO過程的針對各類場景的解決方案,根據經過發起方的不一樣又可分爲兩類,主動同步和被動同步。主動同步是向認證站點獲取ticket並同步自身登陸態,被動同步是由認證站點向當前站點同步登陸態。
通常網上的資料會有一個專門用做認證登陸的站點,好比a.com和b.com站點都從sso.a.com獲取認證狀態。其實在本文中就是把a站點用做sso站點了,原理上是一致的。
爲了這一套方案落地的時候,業務開發同事無需關注這部分實現細節並編寫相應的同步代碼,咱們把他寫入了總體框架裏面,主要作了一下兩件事:
更多關於sso認證方面的能夠參考OAuth2的流程,這套流程用於不可信站點之間的認證在安全方面會更加成熟些,也是目前微信採用的認證流程。
FYI: