今天寫一篇關於多域名下單點登陸的實現。node
有這麼個場景,公司下有多個不一樣域名的站點,咱們指望用戶在任意一個站點下登陸後,在打開另外幾個站點時,也是已經登陸的狀態,這麼一過程就是單點登陸。redis
由於多個站點都是用的同一套用戶體系,因此單點登陸能夠免去用戶重複登陸,讓用戶在站點切換的時候更加流暢,甚至是無感知。跨域
單點登陸所要實現的就是,某一站點登陸後,將其登陸態會同步到其餘另外幾個站點。瀏覽器
咱們分兩部分,先說單個站點的登陸流程,在說同步登陸態的流程。緩存
nodejs
,緩存採用 redis
。session
的 cookies
維繫,採用 cookie
做爲登陸憑證是目前比較主流的方式。session
信息用 redis
承載,從數據層面上看, redis
中存儲 session
對象的 key
即是 cookie
中的 value
key
是由 UUID
生成的惟一標識session
與 cookie
保持對應, session
對象建立與修改都會觸發服務端往瀏覽器寫入 cookie
咱們先看單個站點的登陸流程安全
session
對象,此時 session
中沒有用戶信息,同時服務端往瀏覽器寫入 cookie
session
對象,更新緩存 redis
咱們來畫個圖,以下一個站點完成登陸後,接下來就是如何讓其餘站點也擁有登陸態。 既然登陸態是由 cookie
和 session
決定的,而 cookie
又是由 session
寫入的,那麼也就是說,只要把 session
同步到其它站點,其它站點只要獲取到 session
後,就能夠在該域名建立或更新 cookie
,這樣一來,兩個不一樣域名下的站點就擁有相同的登陸信息了。服務器
所以,同步登陸態其實就是,如何同步 session
的問題。cookie
而咱們的 session
是採用 redis
做爲載體,那麼其餘站點只要能獲取到 redis
中存儲的用戶信息,不就能夠建立本身的 session
對象了麼?session
沒錯!如何同步 session
的問題,就變成了如何讓其餘站點從 redis
中獲取用戶信息,也就是如何讓其餘站點知道存儲該用戶信息的 redis key
架構
到了這一步,咱們須要解決的問題就很明顯啦:如何在不一樣站點間傳輸用戶憑證。
爲便於描述,咱們假設有兩個站點,分別爲A站點和B站點。由於A、B站點的域名不一樣,基於同源策略, cookie
是無法共享的,因此咱們採起主動請求的方式,將用戶惟一憑證經過接口傳過去。大體流程以下
AES
或者 RSA
session
對象,寫入B站點域名下的 cookie
信息基於上圖,咱們完善同步的時序圖
上面描述的是當用戶首次登陸時的同步流程,還須要考慮其餘場景,好比,B站點得到的登陸態失效了,這時候訪問B站點頁面,就須要在一次前往A站點同步登陸態。
B站點上的頁面分爲兩種,一種是須要登陸態才能夠訪問的,一種是不須要登陸態就能夠訪問的。
第一種狀況下,須要重定向到A站點,可爲啥要繞回去A站點呢?由於此時咱們也不知道A站點的登陸態是否也失效了,因此須要回到A站點判斷A站點當前的登陸態,若A站點登陸態也失效了,那麼就去登錄頁進行從新登陸,若A站點是有登錄態的,那麼只要在作一次同步登陸態的操做便可。
第二種狀況,雖然B頁面不須要登陸態就能夠查看,可是企業網站每每會在頁面的head部分標記用戶的登陸態,因此爲了讓這部分的顯示正常,咱們在當前頁面異步的去更新登陸態便可。
咱們仍是來畫圖,清晰一些,以下
如有其餘場景,處理的邏輯與這個相似,本質無非就是在獲取一次憑證,從新更新站點緩存。
由於要在A站點請求B域名下的接口,因此會有跨域問題,跨域問題經常使用的解決方式有以下幾種
JSONP
很常見很通用的一種方式Image
利用 Image src
能夠繞過同源策略,因此經過構建一個 Image
發送給請求也是可行的,同時服務端也不須要作太多修改。CORS
老的瀏覽器就無法支持,須要在服務端設置 Access-Control-Allow-Origin
,容許任何域或指定的域發起的請求均可以獲取當前服務器的數據。服務端主要圍繞 session
對象展開,以前詳細寫過一篇基於 koa2
實現 session
的原理和具體實現,傳送門 : Node工程-構建優秀的Session機制
文章主要是已方案爲主,就不放上詳細的代碼了,其實有了具體方案,代碼的實現就不難啦。
多站點單點登陸確定還有其餘優秀的解決方案,歡迎小夥伴們評論區一塊兒交流探討呀~