1. 程式人生 > >單點登入的解決方案

單點登入的解決方案

背景

專案組的多個子專案想要實現統一登入,也就是多個專案共用一個登入頁面,在A專案登入成功時,訪問B專案頁面時是不用登入的。

先說一波cookie的概念

在瀏覽器中,開啟控制檯,選擇Application,點選cookie下面的子選項,就可以看到cookie了。
《單點登入的解決方案》
cookie是在伺服器端生成的,返回給客戶端,由客戶端來儲存。上圖列表中每一條都是一個cookie。

Name :名稱,一個唯一確定cookie的名稱。
Value : 值,對應的name的值。
Domain :域, cookie對哪個域是有效的,所有向該域傳送的請求都會包含這個cookie資訊,cookie是繫結在特定的域名下面的。
Path :路徑,指定域下面的這個路徑的請求, 傳送請求時,才會帶上這個cookie。
Expires: cookie的過期時間。
HTTP: HttpOnly,客戶端指令碼是否可訪問,上圖中打勾的都是不可訪問的。

例如 x-auth-token (假定x-auth-token的域為fairy.dev.com) 的 path如果被設定成/books,那麼fairy.dev.com/books這個路徑下面的請求才會帶x-auth-token。
token是寫在cookie集合裡面的一個cookie。例如圖中的 x-auth-token就是token。

統一登入

開啟A專案的登入頁面fairy.dev.com/login 進入登入頁面。
登入頁面裡面會嵌入一個iframe,把使用者名稱、密碼會提交到 統一登入的伺服器 id.common.com。登入成功後伺服器端會生成一個token返回給客戶端。這時token的域是id.common.com ,也就是說,訪問fairy.dev.com下面的頁面並不會帶上這個token,只有訪問id.common.com下面的東西,客戶端發起請求的時候才會帶上這個token。
但是現在我們要進入的主頁是fairy.dev.com/index 。所以我們要copy一份這個token,到fairy.dev.com 這個域下面。這個token不是在cookie裡面嗎?從 document.cookie 直接去拿不就好了嘛?2333,並不行的,伺服器端返回的token設定到cookie裡面設定成HttpOnly。客戶端腳本里面是拿不到的。所以我們要讓伺服器端返回這個token。
講道理,輸入使用者名稱、密碼驗證成功就應該跳轉到fairy.dev.com/index ,但是,目前我們的cookie裡面還沒有fairy.dev.com 這個域下面的token。在請求fairy.dev.com/index這個頁面的時候, 發一個get請求,採用jsonp的方式,去請求一個id.common.com下面的一個js檔案,例如 id.common.com/authApi.js 。
客戶端傳送這個get請求的時候會帶上id.common.com 的token,我們通過這個請求去伺服器端請求這個token,當伺服器端返回這個token的時候,就會把這個token寫到fairy.dev.com這個域下面。
Ok,有了這個域下面的token,那麼後面的fairy.dev.com 下面的請求都會帶上這個token。登入成功!

那麼B專案此時要開啟頁面是不用登入的,如果專案結構是fairy.dev.com/a 、fairy.dev.com/b這個樣子的話,那麼這兩個都是同一個域,登入成功fairy.dev.com/a,再去訪問fairy.dev.com/b自然是可以訪問的。
如果是a.dev.com, b.dev.com 這兩個專案要共享cookie。當你登入了a.dev.com的時候,我們的cookie裡面有了id.common.com 的token。請求b.dev.com下面的頁面的時候,同樣是用jsonp的方式發一個get請求把伺服器端返回的token寫到b.dev.com 域下面。b.dev.com下面的頁面也就都可以訪問了。
至此,我們也就實現了統一登入。下面簡單說一下客戶端和伺服器端設定cookie,大神請略過~

客戶端設定cookie vs 伺服器端設定cookie

客戶端設定cookie,document.cookie 可以訪問到,不安全
《單點登入的解決方案》


document.cookie = encodeURIComponent(‘wang’) + “=“ + encodeURIComponent(‘2333’);//就可以在cookie集合中加入 wang=23333
這個字串會被新增到現有的cookie集合中,設定document.cookie並不會覆蓋cookie,除非設定的cookie名稱已經存在。
這樣新增進cookie集合中的cookie是document.cookie可以訪問到的,客戶端指令碼可以訪問的。
《單點登入的解決方案》
如圖,可以看到我們新增的wang httpOnly並沒有勾選。

伺服器端 setCookie,document.cookie 不可訪問,相對來說安全一些
通過在響應頭裡面加一個Set-cookie欄位,把cookie寫入到cookie集合裡面。

如有錯誤,懇請指正。