多站點單點登陸實現方案

今天寫一篇關於多域名下單點登陸的實現。node

有這麼個場景,公司下有多個不一樣域名的站點,咱們指望用戶在任意一個站點下登陸後,在打開另外幾個站點時,也是已經登陸的狀態,這麼一過程就是單點登陸。redis

由於多個站點都是用的同一套用戶體系,因此單點登陸能夠免去用戶重複登陸,讓用戶在站點切換的時候更加流暢,甚至是無感知。跨域

單點登陸所要實現的就是,某一站點登陸後,將其登陸態會同步到其餘另外幾個站點。瀏覽器

咱們分兩部分,先說單個站點的登陸流程,在說同步登陸態的流程。緩存

登陸相關架構

  • 服務端採用 nodejs ,緩存採用 redis
  • 用戶登陸憑證採用基於 sessioncookies 維繫,採用 cookie 做爲登陸憑證是目前比較主流的方式。
  • session 信息用 redis 承載,從數據層面上看, redis 中存儲 session 對象的 key 即是 cookie 中的 value
  • key是由 UUID 生成的惟一標識
  • 爲了保證 sessioncookie 保持對應, session 對象建立與修改都會觸發服務端往瀏覽器寫入 cookie

登陸流程

咱們先看單個站點的登陸流程安全

  1. 用戶首次打開站點,服務端生成 session 對象,此時 session 中沒有用戶信息,同時服務端往瀏覽器寫入 cookie
  2. 用戶觸發登陸操做
  3. 服務端校驗參數處理登陸邏輯後,生成用戶信息,將用戶信息寫入 session 對象,更新緩存 redis 咱們來畫個圖,以下

login

同步登陸態

一個站點完成登陸後,接下來就是如何讓其餘站點也擁有登陸態。 既然登陸態是由 cookiesession 決定的,而 cookie 又是由 session 寫入的,那麼也就是說,只要把 session 同步到其它站點,其它站點只要獲取到 session 後,就能夠在該域名建立或更新 cookie ,這樣一來,兩個不一樣域名下的站點就擁有相同的登陸信息了。服務器

所以,同步登陸態其實就是,如何同步 session 的問題。cookie

而咱們的 session 是採用 redis 做爲載體,那麼其餘站點只要能獲取到 redis 中存儲的用戶信息,不就能夠建立本身的 session 對象了麼?session

沒錯!如何同步 session 的問題,就變成了如何讓其餘站點從 redis 中獲取用戶信息,也就是如何讓其餘站點知道存儲該用戶信息的 redis key架構

到了這一步,咱們須要解決的問題就很明顯啦:如何在不一樣站點間傳輸用戶憑證。

爲便於描述,咱們假設有兩個站點,分別爲A站點和B站點。由於A、B站點的域名不一樣,基於同源策略, cookie 是無法共享的,因此咱們採起主動請求的方式,將用戶惟一憑證經過接口傳過去。大體流程以下

  1. A站點完成登陸邏輯後,將用戶憑證返回到瀏覽器,爲了安全性,在傳輸憑證前,對憑證進行加密,可採用 AES 或者 RSA
  2. A站點的客戶端獲取到憑證後,調用B站點提供的同步登陸態接口,將憑證傳過去
  3. B站點的服務端獲取到憑證,解密,查詢緩存中的用戶信息,建立 session 對象,寫入B站點域名下的 cookie 信息
  4. B站點的登陸態同步完成。

基於上圖,咱們完善同步的時序圖

同步登陸態的場景

上面描述的是當用戶首次登陸時的同步流程,還須要考慮其餘場景,好比,B站點得到的登陸態失效了,這時候訪問B站點頁面,就須要在一次前往A站點同步登陸態。

B站點上的頁面分爲兩種,一種是須要登陸態才能夠訪問的,一種是不須要登陸態就能夠訪問的。

第一種狀況下,須要重定向到A站點,可爲啥要繞回去A站點呢?由於此時咱們也不知道A站點的登陸態是否也失效了,因此須要回到A站點判斷A站點當前的登陸態,若A站點登陸態也失效了,那麼就去登錄頁進行從新登陸,若A站點是有登錄態的,那麼只要在作一次同步登陸態的操做便可。

第二種狀況,雖然B頁面不須要登陸態就能夠查看,可是企業網站每每會在頁面的head部分標記用戶的登陸態,因此爲了讓這部分的顯示正常,咱們在當前頁面異步的去更新登陸態便可。

咱們仍是來畫圖,清晰一些,以下

login-page

如有其餘場景,處理的邏輯與這個相似,本質無非就是在獲取一次憑證,從新更新站點緩存。

跨域請求

由於要在A站點請求B域名下的接口,因此會有跨域問題,跨域問題經常使用的解決方式有以下幾種

  1. JSONP 很常見很通用的一種方式
  2. Image 利用 Image src 能夠繞過同源策略,因此經過構建一個 Image 發送給請求也是可行的,同時服務端也不須要作太多修改。
  3. CORS 老的瀏覽器就無法支持,須要在服務端設置 Access-Control-Allow-Origin,容許任何域或指定的域發起的請求均可以獲取當前服務器的數據。

session對象設計

服務端主要圍繞 session 對象展開,以前詳細寫過一篇基於 koa2 實現 session 的原理和具體實現,傳送門 : Node工程-構建優秀的Session機制

小結

文章主要是已方案爲主,就不放上詳細的代碼了,其實有了具體方案,代碼的實現就不難啦。

多站點單點登陸確定還有其餘優秀的解決方案,歡迎小夥伴們評論區一塊兒交流探討呀~

相關文章
相關標籤/搜索