基于session會(huì)話的登錄認(rèn)證機(jī)制
該機(jī)制的核心在于服務(wù)器session和客戶端sessionId的交互。用戶登錄完成后,服務(wù)器會(huì)構(gòu)建用戶會(huì)話session坠韩,會(huì)話內(nèi)包含了用戶標(biāo)志及登錄狀態(tài)储笑,并向?yàn)g覽器返回sessoinId茧泪。之后用戶在做其他接口請(qǐng)求時(shí),將sessionId攜帶上聋袋。服務(wù)器檢索到會(huì)話session并進(jìn)行登錄鑒權(quán)判斷队伟。
整個(gè)機(jī)制是十分簡(jiǎn)單明了的,但在設(shè)計(jì)細(xì)節(jié)上幽勒,還是由很多發(fā)揮的空間嗜侮。我們先看一看session會(huì)話登錄認(rèn)證機(jī)制的基本流程
認(rèn)證過程大致如下:
- 用戶輸入用戶名、密碼或者用短信驗(yàn)證碼方式登錄系統(tǒng)啥容;
- 服務(wù)端驗(yàn)證后锈颗,創(chuàng)建一個(gè) Session 信息,并且將 SessionID 存到 cookie咪惠,發(fā)送回瀏覽器击吱;
- 下次客戶端再發(fā)起請(qǐng)求,自動(dòng)帶上 cookie 信息遥昧,服務(wù)端通過 cookie 獲取 Session 信息進(jìn)行校驗(yàn)覆醇;
問題點(diǎn):
會(huì)話信息直接存儲(chǔ)在什么地方? 對(duì)于用戶量少的非分布式web系統(tǒng)渠鸽,可以直接使用代碼框架的session能力叫乌。反之,則需要一套緩存服務(wù)(redis)在多臺(tái)web服務(wù)器之間共享session會(huì)話徽缚。
cookie 存在 CSRF(跨站請(qǐng)求偽造)的風(fēng)險(xiǎn)憨奸。sessionId的cookie屬性設(shè)置為httpOnly和secure,保證cookie值不能被前端js代碼讀取到凿试;通過校驗(yàn)reffer header是否合法排宰,防止非自有web系統(tǒng)發(fā)起的請(qǐng)求;通過使用https協(xié)議那婉,防止黑客冒充合法的web系統(tǒng)板甘。
用戶會(huì)話保持和失效——用戶登出則服務(wù)器session清除。用戶長(zhǎng)時(shí)間不操作用戶狀態(tài)失效(設(shè)定緩存時(shí)間)详炬,用戶持續(xù)發(fā)起請(qǐng)求則用戶狀態(tài)保持登錄(會(huì)話快過期時(shí)刷新失效時(shí)間)盐类,瀏覽器關(guān)閉重開是否保持會(huì)話可通過cookie屬性設(shè)置。
sessionId理論上還能放置在什么地方呛谜?除了放置在cookie里在跳,理論上還可以放置在header中,body中隐岛,url路徑中猫妙。放header中是可行的,但一般是在app應(yīng)用里聚凹。對(duì)于web應(yīng)用割坠,還需把sessionId先存儲(chǔ)在localstorage齐帚,那樣才能在新開瀏覽器tab時(shí)讀取重新放置到header中。放在body里理論上可以彼哼,但對(duì)于服務(wù)端的鑒權(quán)會(huì)更麻煩对妄。放在url里則是不安全的挖腰,可通過csrf被黑客截取到径荔。
基于token鑒權(quán)的登錄認(rèn)證機(jī)制
token鑒權(quán)是一種直接把用戶的登錄憑證直接存到客戶端的方案昏苏。在用戶登錄驗(yàn)證成功之后长窄,將登錄憑證做數(shù)字簽名和加密之為token返回給客戶端之斯。用戶在做其他接口請(qǐng)求時(shí)忆某,將token攜帶上衡载。服務(wù)器將該token解密驗(yàn)簽判斷其有效性允乐。
整個(gè)機(jī)制的關(guān)鍵在于token的生成和驗(yàn)證
問題:
經(jīng)過簽名加密后篓吁,token字符串會(huì)很長(zhǎng)茫因,但里面有效信息占比較小,同時(shí)也影響性能杖剪。 盡量減少token里的信息量冻押,最簡(jiǎn)單的形式可以只包含用戶id,憑證創(chuàng)建時(shí)間和過期時(shí)間三個(gè)值盛嘿。
token如何保證每次登錄的安全隨機(jī)洛巢? 如上,添加上時(shí)間戳可以保證每次登錄的token值都不一樣次兆。
用戶會(huì)話保持和失效——用戶登出則清理客戶端token稿茉,用戶長(zhǎng)時(shí)間不操作用戶狀態(tài)失效(token中含緩存時(shí)間),用戶持續(xù)發(fā)起請(qǐng)求則用戶狀態(tài)保持登錄(每次請(qǐng)求刷新token返回)芥炭,瀏覽器關(guān)閉重開是否保持會(huì)話token保存位置決定漓库。
token放置的位置≡膀穑可以放在cookie中渺蒿,CSRF風(fēng)險(xiǎn)同會(huì)話管理。每次請(qǐng)求都可以無感刷新token彪薛。對(duì)于app客戶端茂装。放在header上,則可能存儲(chǔ)在localstorage或sessionStorage里善延,其生命周期影響了會(huì)話保持训唱。
兩類登錄認(rèn)證機(jī)制的對(duì)比
這兩種登錄認(rèn)證機(jī)制差異還是蠻大的。
從原理層面上看挚冤,session會(huì)話機(jī)制中,服務(wù)器為你保管了登錄憑證赞庶,然后給了客戶端一個(gè)信物训挡“闹瑁客戶端帶著信物訪問,服務(wù)器能根據(jù)這個(gè)信息找到登錄憑證就是有效的澜薄;token認(rèn)證機(jī)制中为肮,服務(wù)器將登錄憑證打上記號(hào)鎖在盒子里再給到客戶端》艟客戶端帶著這個(gè)上鎖的盒子訪問颊艳,服務(wù)器拿出他的鎖打開并檢查記號(hào),都對(duì)上了則說明登錄憑證可以使用忘分。當(dāng)然棋枕,登錄憑證里也有失效
從效果層面上看,session會(huì)話機(jī)制中妒峦,服務(wù)器需要自己騰出空間保存憑證和記錄重斑,而token認(rèn)證機(jī)制中,服務(wù)器則只需保管好鑰匙肯骇,信息本身是保存在客戶端窥浪。因此,session會(huì)話需要更多存儲(chǔ)空間笛丙;token認(rèn)證機(jī)制需要額外的token解析時(shí)間漾脂,本身不存儲(chǔ)任何用戶的登錄狀態(tài)
但有時(shí)候,又不是那么絕對(duì)胚鸯。例如token鑒權(quán)中骨稿,對(duì)于強(qiáng)業(yè)務(wù)的web系統(tǒng),后端web服務(wù)必然也還會(huì)再關(guān)聯(lián)個(gè)session會(huì)話做業(yè)務(wù)邏輯的處理蠢琳;對(duì)于要求用戶單端登錄的情況啊终,如果同時(shí)異地登錄,舊的token要求被踢下傲须,此時(shí)后端web服務(wù)就得存儲(chǔ)用戶token及ip或設(shè)備等信息蓝牲。具體的設(shè)計(jì)原則,還是得看系統(tǒng)的業(yè)務(wù)屬性泰讽。畢竟例衍,一個(gè)系統(tǒng),可不會(huì)僅包含用戶登錄鑒權(quán)已卸。
附:初始登錄鑒權(quán)
自有賬號(hào)體系登錄
略
三方賬號(hào) Oauth2.0 登錄流程
流程示意圖:
[圖片上傳失敗...(image-a55a38-1609677363093)]
- 用戶選擇華為帳號(hào)登錄佛玄,開發(fā)者應(yīng)用發(fā)起授權(quán)碼Code請(qǐng)求。
- 華為帳號(hào)服務(wù)器呈現(xiàn)授權(quán)頁(yè)面給用戶累澡,用戶確認(rèn)授權(quán)梦抢。
- 華為帳號(hào)服務(wù)器通過開發(fā)者應(yīng)用配置的回調(diào)地址,返回授權(quán)碼Code愧哟。(
- 開發(fā)者應(yīng)用發(fā)起Code換Token請(qǐng)求奥吩。
- 華為帳號(hào)服務(wù)器返回憑證(Access Token)哼蛆、用戶信息(ID Token)。
- 之后用上一步獲取的 access_token 去請(qǐng)求華為賬號(hào)服務(wù)器獲取用戶的基本信息霞赫,例如頭像腮介、昵稱等;
- 保存到用戶憑證中端衰,完成登錄叠洗。
自有系統(tǒng) SSO單點(diǎn)登錄
流程示意圖:
- 用戶向后臺(tái)業(yè)務(wù)系統(tǒng)發(fā)起請(qǐng)求時(shí),先驗(yàn)證局部登錄會(huì)話是否創(chuàng)建旅东。如果未創(chuàng)建灭抑,則先跳轉(zhuǎn)到SSO單點(diǎn)登錄系統(tǒng)進(jìn)行登錄操作.
- SSO認(rèn)證中心引導(dǎo)用戶登錄,完成登錄驗(yàn)證
- 驗(yàn)證OK玉锌,則生成ticket.并將User對(duì)象轉(zhuǎn)化為JSON數(shù)據(jù)名挥,創(chuàng)建全局會(huì)話。(這里基于cookie-session的機(jī)制)
- 攜帶ticket跳轉(zhuǎn)回業(yè)務(wù)系統(tǒng)的前臺(tái)頁(yè)面 (當(dāng)業(yè)務(wù)系統(tǒng)與SSO認(rèn)證中心同域的情況下主守,ticket可直接放在域名cookie下)
- 用戶重新在瀏覽器頁(yè)面發(fā)起了操作
- 業(yè)務(wù)系統(tǒng)后臺(tái)向SSO認(rèn)證中心驗(yàn)證ticket合法性禀倔,以獲取用戶登錄憑證。并在自己的服務(wù)域名下創(chuàng)建局部會(huì)話参淫。
以上兩個(gè)流程實(shí)際上大同小異救湖,都遵循外部鑒權(quán)系統(tǒng)的兩個(gè)核心步驟————鑒權(quán)認(rèn)證中心(外部賬號(hào)系統(tǒng)、自有SSO認(rèn)證中心)在登錄完成后頒發(fā)令牌涎才,業(yè)務(wù)系統(tǒng)拿著該令牌向鑒權(quán)認(rèn)證中心請(qǐng)求驗(yàn)證鞋既。 前一步可以通過cookie或url參數(shù)的性質(zhì)通過前端傳到業(yè)務(wù)系統(tǒng),該令牌被泄露了也無關(guān)緊要耍铜;第二步則由后臺(tái)服務(wù)向鑒權(quán)中心發(fā)起認(rèn)證邑闺,這里則需要服務(wù)之間的互信。oauth機(jī)制中棕兼,可以通過appid和secret來保證互信陡舅。SSO認(rèn)證中心則可以通過秘鑰管理的方式來保證互信。