單點登陸(SingleSignOn,SSO
),就是經過用戶的一次性鑑別登陸。當用戶在身份認證服務器上登陸一次之後,便可得到訪問單點登陸系統中其餘關聯繫統和應用軟件的權限,同時這種實現是不須要管理員對用戶的登陸狀態或其餘信息進行修改的,這意味着在多個應用系統中,用戶只需一次登陸就能夠訪問全部相互信任的應用系統。前端
這裏用一張圖說明sso流程git
假設zss
系統前端域名爲zsstest.zuel.com:8081
,後端域名爲zsstest.zuel.com:8887
;sso
系統前端域名爲sso.zuel.com:8082
,後端域名爲sso.zuel.com:8888
。咱們跟着原理流程圖來說解如何實現單點登陸。github
假設zss
系統首頁zsstest.zuel.com:8081/index
有一個/api/getUserinfo
請求獲取用戶信息,當第一次用瀏覽器打開首頁時就發送了該請求,zss-os
後端接收到該請求,發現請求沒有攜帶cookie
身份(也就是token
),返回401
給zss-fe
前端,前端響應攔截器攔截到返回數據,發現返回數據爲401
,因而重定向到sso
的登陸頁(sso.zuel.com:8082/login
),並把zss
系統首頁做爲參數拼接到重定向地址的後面(window.location.href=http://sso.zuel.com:8082/login?service=http://zsstest.zuel.com:8081/index
)。當登陸成功時,sso-os
後端根據帳戶和時間生成token
(使用jwt
包),經過設置響應頭Set-Cookie
屬性種下cookie
,並把token
存到redis
集羣中,最後重定向到service
參數url
。redis
重定向到service
參數url
又會再次發送/api/getUserinfo
請求,後端zss-os
就會去校驗cookie
身份(到redis
集羣中去找是否有該身份的token
存在),若校驗合法,則返回請求結果,不然返回401
又再次重定向到sso
登陸頁。chrome
這裏使用redis
集羣的目的是zss
系統和sso
系統均可以訪問到redis
存儲的數據。後端
上面還有許多坑,在設置cookie
時須要注意:api
withCredentials=true
時, 後端配置Access-Control-Allow-Origin
不能爲*
, 必須是相應地址withCredentials=true
時, 後端需配置Access-Control-Allow-Credentials
Access-Control-Allow-Headers
爲對應的請求頭集合set-cookie
若想在瀏覽器cookie
中顯示而且在前端請求頭自動攜帶,那麼設置cookie
時domian
就必須與前端當前頁域名、請求域名同樣。好比,上述domain
設置爲.zuel.com
,那麼zsstest.zuel.com:8081/index
頁面的cookie
將會顯示,zsstest.zuel.com:8887/api/getUserInfo
請求頭也會自動攜帶domain
域名的cookie
name、path、domain
相同的cookie
纔是同一個cookie
參考:
https://juejin.im/post/5c2490...
https://juejin.im/post/5c0f2a...
https://juejin.im/post/59d1f5...瀏覽器
單點登陸的實現:
上面生成token
使用了時間,也就是每次登陸成功生成的token
都會不一樣,當用戶A
使用chrome
登入系統生成的token
爲t1
,redis
存儲t1
,瀏覽器cookie
存儲t1
,而後用戶A
換個Firefox
登陸,生成token
爲t2
,redis
存儲t2
,瀏覽器cookie
存儲t2
。當用戶A
在chrome
刷新頁面,請求攜帶的cookie
仍是t1
,但redis
存儲的cookie
已經變成t2
,因此身份驗證不會經過,頁面會重定向到sso
登陸頁服務器
統一登錄實現效果:cookie