昆明公司網(wǎng)站建設(shè)一條龍全包(sessionid和token)session token jwt,
導(dǎo) 讀圖解最基礎(chǔ)的認(rèn)證方式:Session-Cookie,依次解釋其基本步驟、偽代碼、缺點(diǎn)以及相應(yīng)的解決方案引言由于 HTTP 協(xié)議是無狀態(tài)的,完成操作關(guān)閉瀏覽器后,客戶端和服務(wù)端的連接就斷開了,所以我們必須要有一種機(jī)制來保證客戶端和服務(wù)端之間會話的連續(xù)性,也稱為認(rèn)證,最常見的應(yīng)用場景就是保持用戶的登錄態(tài)。
最基本的認(rèn)證方式,就是使用 Sesson-Cookie。30s 圖解 Sesson-Cookie 認(rèn)證以保持用戶登錄態(tài)為例,Sesson-Cookie 認(rèn)證的具體步驟如下:
1)客戶端(瀏覽器): 向服務(wù)器發(fā)送登錄信息(用戶名和密碼)來請求登錄校驗(yàn);2)服務(wù)端: 驗(yàn)證登錄信息,驗(yàn)證通過后服務(wù)器(比如 Tomcat)會自動為此次請求開辟一塊內(nèi)存空間(一個(gè) Session 對象),可以手動將用戶信息(比如登錄保持時(shí)間是否過期)存在 Session 對象中。
然后,服務(wù)器會自動為這個(gè) Sesson 對象生成一個(gè)唯一的標(biāo)識 sessionID ,并在 HTTP 響應(yīng)頭(Header)的 Set-Cookie:JSESSIONID=XXXXXXX 中設(shè)置這個(gè) seesionID。
所以說,Session 的實(shí)現(xiàn)是依賴于 Cookie 的3)客戶端: 收到服務(wù)端的響應(yīng)后會解析響應(yīng)頭,從而根據(jù) set-Cookie 將 sessonId 保存在本地 Cookie 中,這樣,客戶端(瀏覽器)在下次 HTTP 請求時(shí)請求頭會自動附上該域名下的 Cookie 信息;
4)服務(wù)端: 接收客戶端請求時(shí)會去解析請求頭 Cookie 中的 sessonId,然后根據(jù)這個(gè) sessonId 去找 Sesson 對象,從而獲取到用戶信息;可以通過攔截器在每次請求前嘗試獲取 Sesson 對象:Session 存活期間,我們認(rèn)為客戶端一直處于活躍狀態(tài)(用戶處于登錄態(tài)),一旦 Session 超期過時(shí),那么就可以認(rèn)為客戶端已經(jīng)停止和服務(wù)器進(jìn)行交互了(用戶退出登錄)。
如果遇到禁用 Cookie 的情況,一般的做法就是把這個(gè) sessionID 放到 URL 參數(shù)中這也是經(jīng)常在面試中會被問到的問題可能會有同學(xué)問為啥不直接把數(shù)據(jù)全部存在 Cookie 中,還整個(gè) Session 出來然后把 sessionID 存在 Cookie 中的?。
Cookie 長度的限制:首先,最基本的,Cookie 是有長度限制的,這限制了它能存儲的數(shù)據(jù)的長度性能影響:Cookie 確實(shí)和 Session 一樣可以讓服務(wù)端程序跟蹤每個(gè)客戶端的訪問,但是每次客戶端的訪問都必須傳回這些 Cookie,那如果 Cookie 中存儲的數(shù)據(jù)比較多的話,這無疑增加了客戶端與服務(wù)端之間的數(shù)據(jù)傳輸量,增加了服務(wù)器的壓力。
安全性:Session 數(shù)據(jù)其實(shí)是屬于服務(wù)端的數(shù)據(jù),而 Cookie 屬于客戶端,把本應(yīng)在 Session 中存儲的數(shù)據(jù)放到客戶端 Cookie,使得服務(wù)端數(shù)據(jù)延伸到了外部網(wǎng)絡(luò)及客戶端,顯然是存在安全性上的問題的。
當(dāng)然我們可以對這些數(shù)據(jù)做加密,不過從技術(shù)來講物理上不接觸才是最安全的附加閱讀Sesson-Cookie 認(rèn)證偽代碼登錄:
攔截器:每次請求前去找 Sesson 對象,從而獲取到用戶信息
可以看出來,在一次會話當(dāng)中,兩個(gè)請求獲取到的 Session 對象實(shí)際上是同一個(gè)對象上面已經(jīng)提到,服務(wù)器是根據(jù) cookie 中的 sessionID 來找到 Session 對象的,但以上代碼中我們只是手動將用戶數(shù)據(jù)設(shè)置到了 Session 中,并沒有出現(xiàn)任何關(guān)于 Cookie 的代碼(將 SessionId 設(shè)置到 Cookie 中)。
很明顯,這些肯定都是服務(wù)器(比如 Tomcat)自動完成的了在第一次獲取 Session 即調(diào)用 request.getSession() 的時(shí)候,服務(wù)器會自動創(chuàng)建一個(gè) Session 對象(Session 是一個(gè)集合,并且是一個(gè) Map 集合),并且存入服務(wù)器的 Session 集合中以 SessionId 為標(biāo)識鍵,也就是說根據(jù) SessionId 即可取到對應(yīng) Session 的引用。
同時(shí)也會創(chuàng)建一個(gè)鍵名為 JSESSIONID 的 Cookie 并且返回給瀏覽器,該 Cookie 的值即為 SessionId這個(gè)存儲著 SessionId 的 Cookie 會跟著請求上傳到服務(wù)器,所以說,在同一會話當(dāng)中,不管哪個(gè)請求拿到的都是同一個(gè) Session 對象。
Sesson-Cookie 認(rèn)證的缺點(diǎn)與解決方案這種機(jī)制在單體應(yīng)用時(shí)代應(yīng)用非常廣泛,但是,隨著分布式時(shí)代的到來,Session 的缺點(diǎn)也逐漸暴露出來舉個(gè)例子,比如我們有多個(gè)服務(wù)器,客戶端 1 向服務(wù)器發(fā)送了一個(gè)請求,由于負(fù)載均衡的存在,該請求被轉(zhuǎn)發(fā)給了服務(wù)器 A,于是服務(wù)器 A 創(chuàng)建并存儲了這個(gè) Session。
緊接著,客戶端 1 又向服務(wù)器發(fā)送了一個(gè)請求,但是這一次請求被負(fù)載均衡給了服務(wù)器 B,而服務(wù)器 B 這時(shí)候是沒有存儲服務(wù)器 A 的 Session 的,這就導(dǎo)致 Session 的失效。
明明用戶在上一個(gè)界面還是登錄的,跳到下一個(gè)界面就退出登錄了,這顯然不合理當(dāng)然了,對此的解決方法其實(shí)也有很多種,其實(shí)就是如何解決 Session 在多個(gè)服務(wù)器之間的共享問題:Sesson Replication。
Sesson StickySesson 數(shù)據(jù)集中存儲Session Replication這個(gè)是最容易想到的,既然服務(wù)器 B 沒有服務(wù)器 A 存儲的 Session,那各個(gè)服務(wù)器之間同步一下 Session 數(shù)據(jù)不就完了。
這種方案存在的問題也是顯而易見的:同步 Session 數(shù)據(jù)帶來了額外的網(wǎng)絡(luò)帶寬開銷只要 Session 數(shù)據(jù)有變化,就需要將數(shù)據(jù)同步到所有其他機(jī)器上,機(jī)器越多,同步帶來的網(wǎng)絡(luò)帶寬開銷就越大每臺Web服務(wù)器都要保存所有 Session 數(shù)據(jù),如果整個(gè)集群的 Session 數(shù)據(jù)很多(比如很多人同時(shí)訪問網(wǎng)站的情況),每臺服務(wù)器用于保存 Session 數(shù)據(jù)的內(nèi)存占用會非常嚴(yán)重。
Session Sticky從名稱也能看出來,Sticky,即讓負(fù)載均衡器能夠根據(jù)每次的請求的會話標(biāo)識來進(jìn)行請求的轉(zhuǎn)發(fā),保證一個(gè)會話中的每次請求都能落到同一臺服務(wù)器上面。
存在問題的:如果某臺服務(wù)器宕機(jī)或者重啟了,那么它上面存儲的 Session 數(shù)據(jù)就丟失了,用戶就需要重新進(jìn)行登陸負(fù)載均衡器變?yōu)橐粋€(gè)有狀態(tài)的節(jié)點(diǎn),因?yàn)樗枰4?Session 到具體服務(wù)器的映射,和之前無狀態(tài)的節(jié)點(diǎn)相比,內(nèi)存消耗會更大,容災(zāi)方面會更麻煩。
Session 數(shù)據(jù)集中存儲將每個(gè)服務(wù)器的 Session 數(shù)據(jù)都集中存到外部介質(zhì)比如 Redis 或者 MySQL 中去,然后所有的服務(wù)器都從這個(gè)外部介質(zhì)中拿 Session 就行了
存在的問題也很顯然:過度依賴外部存儲,如果集中存儲 Session 的外部存儲機(jī)器出問題了,就會直接影響到我們的應(yīng)用End.往期推薦
關(guān)注我們陽后兩周,開始恢復(fù)性鍛煉,祝大伙兒身體健康!2022-12-30
美團(tuán)一面:能不能通俗的解釋下為什么要有意向鎖這個(gè)東西?2022-12-27
免疫系統(tǒng):劃了這么多年水,終于有活干了,兄弟們,沖!2022-12-19
五年經(jīng)驗(yàn)的前端社招被問:CPU 和 GPU 有什么區(qū)別?2022-12-13
MySQL 的自增主鍵一定是連續(xù)的嗎?2022-12-06
公眾號@飛天小牛肉 → 分享原創(chuàng)技術(shù)干貨和成長經(jīng)驗(yàn).微信號:jcool1998 |個(gè)人網(wǎng)站:cswiki.top回復(fù)『春秋招』我拉你進(jìn)校招交流群回復(fù)『Echo』免費(fèi)獲取社區(qū)項(xiàng)目手把手教程