單點(diǎn)登錄的三種實(shí)現(xiàn)方式

學(xué)號(hào):17020110019? ? 姓名:高少魁

轉(zhuǎn)載自:https://mp.weixin.qq.com/s/wO11F4e0rJTMXWteVfAxzA

【嵌牛導(dǎo)讀】介紹了三種B/S系統(tǒng)中單點(diǎn)登錄的方式:父域cookie在旱、認(rèn)證中心、LocalStorage跨域。

【嵌牛鼻子】單點(diǎn)登錄? ? 共享登錄狀態(tài)? ? Session共享與多域名共享

【嵌牛正文】

一喧锦、前言

在 B/S 系統(tǒng)中夏伊,登錄功能通常都是基于 Cookie 來(lái)實(shí)現(xiàn)的睹栖。當(dāng)用戶登錄成功后敛瓷,一般會(huì)將登錄狀態(tài)記錄到 Session 中颜懊,或者是給用戶簽發(fā)一個(gè) Token河哑,無(wú)論哪一種方式避诽,都需要在客戶端保存一些信息(Session ID 或 Token ),并要求客戶端在之后的每次請(qǐng)求中攜帶它們璃谨。在這樣的場(chǎng)景下沙庐,使用 Cookie 無(wú)疑是最方便的,因此我們一般都會(huì)將 Session 的 ID 或 Token 保存到 Cookie 中佳吞,當(dāng)服務(wù)端收到請(qǐng)求后拱雏,通過(guò)驗(yàn)證 Cookie 中的信息來(lái)判斷用戶是否登錄 。

單點(diǎn)登錄(Single Sign On, SSO)是指在同一帳號(hào)平臺(tái)下的多個(gè)應(yīng)用系統(tǒng)中底扳,用戶只需登錄一次铸抑,即可訪問(wèn)所有相互信任的應(yīng)用系統(tǒng)。舉例來(lái)說(shuō)花盐,百度貼吧和百度地圖是百度公司旗下的兩個(gè)不同的應(yīng)用系統(tǒng)羡滑,如果用戶在百度貼吧登錄過(guò)之后,當(dāng)他訪問(wèn)百度地圖時(shí)無(wú)需再次登錄算芯,那么就說(shuō)明百度貼吧和百度地圖之間實(shí)現(xiàn)了單點(diǎn)登錄柒昏。

單點(diǎn)登錄的本質(zhì)就是在多個(gè)應(yīng)用系統(tǒng)中共享登錄狀態(tài)。如果用戶的登錄狀態(tài)是記錄在 Session 中的熙揍,要實(shí)現(xiàn)共享登錄狀態(tài)职祷,就要先共享 Session,比如可以將 Session 序列化到 Redis 中届囚,讓多個(gè)應(yīng)用系統(tǒng)共享同一個(gè) Redis有梆,直接讀取 Redis 來(lái)獲取 Session。

當(dāng)然僅此是不夠的意系,因?yàn)椴煌膽?yīng)用系統(tǒng)有著不同的域名泥耀,盡管 Session 共享了,但是由于 Session ID 是往往保存在瀏覽器 Cookie 中的蛔添,因此存在作用域的限制痰催,無(wú)法跨域名傳遞兜辞,也就是說(shuō)當(dāng)用戶在 app1.com 中登錄后,Session ID 僅在瀏覽器訪問(wèn) app1.com 時(shí)才會(huì)自動(dòng)在請(qǐng)求頭中攜帶夸溶,而當(dāng)瀏覽器訪問(wèn) app2.com 時(shí)逸吵,Session ID 是不會(huì)被帶過(guò)去的。實(shí)現(xiàn)單點(diǎn)登錄的關(guān)鍵在于缝裁,如何讓 Session ID(或 Token)在多個(gè)域中共享扫皱。

二、實(shí)現(xiàn)方式一:父域Cookie

在將具體實(shí)現(xiàn)之前捷绑,我們先來(lái)聊一聊 Cookie 的作用域韩脑。

Cookie 的作用域由 domain 屬性和 path 屬性共同決定。domain 屬性的有效值為當(dāng)前域或其父域的域名/IP地址粹污,在 Tomcat 中扰才,domain 屬性默認(rèn)為當(dāng)前域的域名/IP地址。path 屬性的有效值是以“/”開(kāi)頭的路徑厕怜,在 Tomcat 中衩匣,path 屬性默認(rèn)為當(dāng)前 Web 應(yīng)用的上下文路徑。

如果將 Cookie 的 domain 屬性設(shè)置為當(dāng)前域的父域粥航,那么就認(rèn)為它是父域 Cookie琅捏。Cookie 有一個(gè)特點(diǎn),即父域中的 Cookie 被子域所共享递雀,換言之柄延,子域會(huì)自動(dòng)繼承父域中的Cookie。

利用 Cookie 的這個(gè)特點(diǎn)缀程,不難想到搜吧,將 Session ID(或 Token)保存到父域中不就行了。沒(méi)錯(cuò)杨凑,我們只需要將 Cookie 的 domain 屬性設(shè)置為父域的域名(主域名)滤奈,同時(shí)將 Cookie 的 path 屬性設(shè)置為根路徑,這樣所有的子域應(yīng)用就都可以訪問(wèn)到這個(gè) Cookie 了撩满。不過(guò)這要求應(yīng)用系統(tǒng)的域名需建立在一個(gè)共同的主域名之下蜒程,如 tieba.baidu.com 和 map.baidu.com,它們都建立在 baidu.com 這個(gè)主域名之下伺帘,那么它們就可以通過(guò)這種方式來(lái)實(shí)現(xiàn)單點(diǎn)登錄昭躺。

總結(jié):此種實(shí)現(xiàn)方式比較簡(jiǎn)單,但不支持跨主域名伪嫁。

三领炫、實(shí)現(xiàn)方式二:認(rèn)證中心

我們可以部署一個(gè)認(rèn)證中心,認(rèn)證中心就是一個(gè)專門(mén)負(fù)責(zé)處理登錄請(qǐng)求的獨(dú)立的 Web 服務(wù)张咳。

用戶統(tǒng)一在認(rèn)證中心進(jìn)行登錄帝洪,登錄成功后针史,認(rèn)證中心記錄用戶的登錄狀態(tài),并將 Token 寫(xiě)入 Cookie碟狞。(注意這個(gè) Cookie 是認(rèn)證中心的,應(yīng)用系統(tǒng)是訪問(wèn)不到的婚陪。)

應(yīng)用系統(tǒng)檢查當(dāng)前請(qǐng)求有沒(méi)有 Token族沃,如果沒(méi)有,說(shuō)明用戶在當(dāng)前系統(tǒng)中尚未登錄泌参,那么就將頁(yè)面跳轉(zhuǎn)至認(rèn)證中心脆淹。由于這個(gè)操作會(huì)將認(rèn)證中心的 Cookie 自動(dòng)帶過(guò)去,因此沽一,認(rèn)證中心能夠根據(jù) Cookie 知道用戶是否已經(jīng)登錄過(guò)了盖溺。如果認(rèn)證中心發(fā)現(xiàn)用戶尚未登錄,則返回登錄頁(yè)面铣缠,等待用戶登錄烘嘱,如果發(fā)現(xiàn)用戶已經(jīng)登錄過(guò)了,就不會(huì)讓用戶再次登錄了蝗蛙,而是會(huì)跳轉(zhuǎn)回目標(biāo) URL 蝇庭,并在跳轉(zhuǎn)前生成一個(gè) Token,拼接在目標(biāo) URL 的后面捡硅,回傳給目標(biāo)應(yīng)用系統(tǒng)哮内。

應(yīng)用系統(tǒng)拿到 Token 之后,還需要向認(rèn)證中心確認(rèn)下 Token 的合法性壮韭,防止用戶偽造北发。確認(rèn)無(wú)誤后,應(yīng)用系統(tǒng)記錄用戶的登錄狀態(tài)喷屋,并將 Token 寫(xiě)入 Cookie琳拨,然后給本次訪問(wèn)放行。(注意這個(gè) Cookie 是當(dāng)前應(yīng)用系統(tǒng)的屯曹,其他應(yīng)用系統(tǒng)是訪問(wèn)不到的从绘。)當(dāng)用戶再次訪問(wèn)當(dāng)前應(yīng)用系統(tǒng)時(shí),就會(huì)自動(dòng)帶上這個(gè) Token是牢,應(yīng)用系統(tǒng)驗(yàn)證 Token 發(fā)現(xiàn)用戶已登錄僵井,于是就不會(huì)有認(rèn)證中心什么事了。

這里順便介紹兩款認(rèn)證中心的開(kāi)源實(shí)現(xiàn):

1驳棱、Apereo CAS 是一個(gè)企業(yè)級(jí)單點(diǎn)登錄系統(tǒng)批什,其中 CAS 的意思是”Central Authentication Service“。它最初是耶魯大學(xué)實(shí)驗(yàn)室的項(xiàng)目社搅,后來(lái)轉(zhuǎn)讓給了 JASIG 組織驻债,項(xiàng)目更名為 JASIG CAS乳规,后來(lái)該組織并入了Apereo 基金會(huì),項(xiàng)目也隨之更名為 Apereo CAS合呐。

2暮的、XXL-SSO 是一個(gè)簡(jiǎn)易的單點(diǎn)登錄系統(tǒng),由大眾點(diǎn)評(píng)工程師許雪里個(gè)人開(kāi)發(fā)淌实,代碼比較簡(jiǎn)單冻辩,沒(méi)有做安全控制,因而不推薦直接應(yīng)用在項(xiàng)目中拆祈,這里列出來(lái)僅供參考恨闪。

總結(jié):此種實(shí)現(xiàn)方式相對(duì)復(fù)雜,支持跨域放坏,擴(kuò)展性好咙咽,是單點(diǎn)登錄的標(biāo)準(zhǔn)做法。

四淤年、實(shí)現(xiàn)方式三:LocalStorage跨域

前面钧敞,我們說(shuō)實(shí)現(xiàn)單點(diǎn)登錄的關(guān)鍵在于,如何讓 Session ID(或 Token)在多個(gè)域中共享麸粮。

父域 Cookie 確實(shí)是一種不錯(cuò)的解決方案犁享,但是不支持跨域。那么有沒(méi)有什么奇淫技巧能夠讓 Cookie 跨域傳遞呢豹休?

很遺憾炊昆,瀏覽器對(duì) Cookie 的跨域限制越來(lái)越嚴(yán)格。Chrome 瀏覽器還給 Cookie 新增了一個(gè) SameSite 屬性威根,此舉幾乎禁止了一切跨域請(qǐng)求的 Cookie 傳遞(超鏈接除外)凤巨,并且只有當(dāng)使用 HTTPs 協(xié)議時(shí),才有可能被允許在 AJAX 跨域請(qǐng)求中接受服務(wù)器傳來(lái)的 Cookie洛搀。

不過(guò)敢茁,在前后端分離的情況下,完全可以不使用 Cookie留美,我們可以選擇將 Session ID (或 Token )保存到瀏覽器的 LocalStorage 中彰檬,讓前端在每次向后端發(fā)送請(qǐng)求時(shí),主動(dòng)將 LocalStorage 的數(shù)據(jù)傳遞給服務(wù)端谎砾。這些都是由前端來(lái)控制的逢倍,后端需要做的僅僅是在用戶登錄成功后,將 Session ID (或 Token )放在響應(yīng)體中傳遞給前端景图。

在這樣的場(chǎng)景下较雕,單點(diǎn)登錄完全可以在前端實(shí)現(xiàn)。前端拿到 Session ID (或 Token )后,除了將它寫(xiě)入自己的 LocalStorage 中之外亮蒋,還可以通過(guò)特殊手段將它寫(xiě)入多個(gè)其他域下的 LocalStorage 中扣典。

總結(jié):此種實(shí)現(xiàn)方式完全由前端控制,幾乎不需要后端參與慎玖,同樣支持跨域贮尖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市趁怔,隨后出現(xiàn)的幾起案子湿硝,更是在濱河造成了極大的恐慌,老刑警劉巖痕钢,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異序六,居然都是意外死亡任连,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)例诀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)随抠,“玉大人,你說(shuō)我怎么就攤上這事繁涂」八” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵扔罪,是天一觀的道長(zhǎng)秉沼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)矿酵,這世上最難降的妖魔是什么唬复? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮全肮,結(jié)果婚禮上敞咧,老公的妹妹穿的比我還像新娘。我一直安慰自己辜腺,他們只是感情好休建,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著评疗,像睡著了一般测砂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上百匆,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天邑彪,我揣著相機(jī)與錄音,去河邊找鬼胧华。 笑死寄症,一個(gè)胖子當(dāng)著我的面吹牛宙彪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播有巧,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼释漆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了篮迎?” 一聲冷哼從身側(cè)響起男图,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甜橱,沒(méi)想到半個(gè)月后逊笆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岂傲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年难裆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镊掖。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乃戈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亩进,到底是詐尸還是另有隱情症虑,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布归薛,位于F島的核電站谍憔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏主籍。R本人自食惡果不足惜韵卤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崇猫。 院中可真熱鬧沈条,春花似錦、人聲如沸诅炉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涕烧。三九已至月而,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間议纯,已是汗流浹背父款。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人憨攒。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓世杀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肝集。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞻坝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容