前言
- HTTP是一種無(wú)狀態(tài)協(xié)議,為了分別鏈接是誰(shuí)發(fā)起的捌议,需自己去解決這個(gè)問(wèn)題哼拔。不然有些情況下即使是同一個(gè)網(wǎng)站每打開(kāi)一個(gè)網(wǎng)頁(yè),也都要登錄一下瓣颅。而Session和Cookie就是為解決這個(gè)問(wèn)題而提出來(lái)的兩個(gè)機(jī)制倦逐。
應(yīng)用場(chǎng)景
- 登錄網(wǎng)站,今輸入用戶名和密碼登錄了宫补,第二天再打開(kāi)很多情況下就直接打開(kāi)了檬姥。這個(gè)時(shí)候用到的一個(gè)機(jī)制就是cookie曾我。
- session,一個(gè)場(chǎng)景是購(gòu)物車,添加了商品之后客戶端處可以知道添加了哪些商品健民,而服務(wù)器端如何判別呢抒巢?所以也需要存儲(chǔ)一些信息就用到了session.
- Cookie
通俗的講,是訪問(wèn)某些網(wǎng)站后在本地存儲(chǔ)的一些網(wǎng)站相關(guān)信息秉犹,下次訪問(wèn)時(shí)減少一些步驟蛉谜。更準(zhǔn)確的一些說(shuō)法是:Cookie是服務(wù)器在本地機(jī)器上存儲(chǔ)的小段文本,并隨每一個(gè)請(qǐng)求發(fā)送至同一服務(wù)器崇堵,是在客戶端保持狀態(tài)的方案型诚。
-
Cookie的主要內(nèi)容包括,名字筑辨,值俺驶,過(guò)期時(shí)間幸逆,路徑和域棍辕。使用Fiddler抓包就可以看見(jiàn),比方說(shuō)还绘,我們打開(kāi)百度的某個(gè)網(wǎng)站可以看到Headers包括Cookie,如下:
image.png key /value 形式的楚昭。過(guò)期時(shí)間可以設(shè)置,如不設(shè)拍顷,則瀏覽器關(guān)掉就消失了抚太,存儲(chǔ)在內(nèi)存當(dāng)中,否則就按照設(shè)置的時(shí)間才存儲(chǔ)在硬盤(pán)上的昔案,過(guò)期后自動(dòng)清除尿贫,比方說(shuō)開(kāi)關(guān)機(jī)關(guān)閉再打開(kāi)瀏覽器后他都還會(huì)存在,前者稱之為Session cookie ,又叫transient cookie,后者稱之Persistent cookie 又叫 permenent cookie踏揣。路徑和域就是對(duì)應(yīng)的域名庆亡,a網(wǎng)站的cookie自然不能給b用。
一般瀏覽器存儲(chǔ)cookie 最大容量為4k捞稿,所以大量數(shù)據(jù)不要存到cookie又谋。
2.Session
- 存在服務(wù)器的一種用來(lái)存放用戶數(shù)據(jù)的類Hash Table結(jié)構(gòu)
- 瀏覽器第一次發(fā)送請(qǐng)求時(shí),服務(wù)器自動(dòng)生成了一HashTable和一Session ID來(lái)唯一標(biāo)識(shí)這個(gè)HashTable娱局,并將其通過(guò)響應(yīng)發(fā)送到瀏覽器彰亥。瀏覽器第二次發(fā)送請(qǐng)求會(huì)將前一次服務(wù)器響應(yīng)中的Session ID放在請(qǐng)求中一并發(fā)送到服務(wù)器上,服務(wù)器從請(qǐng)求中提取出Session ID衰齐,并和保存的所有Session ID進(jìn)行對(duì)比任斋,找到這個(gè)用戶對(duì)應(yīng)的HashTable。
- 一般這個(gè)值會(huì)有個(gè)時(shí)間限制耻涛,超時(shí)后毀掉這個(gè)值废酷,默認(rèn)30分鐘穴翩。
- 當(dāng)用戶在應(yīng)用程序的 Web頁(yè)間跳轉(zhuǎn)時(shí),存儲(chǔ)在 Session 對(duì)象中的變量不會(huì)丟失而是在整個(gè)用戶會(huì)話中一直存在下去锦积。
- Session的實(shí)現(xiàn)方式和Cookie有一定關(guān)系芒帕。建立一個(gè)連接就生成一個(gè)session id,打開(kāi)幾個(gè)頁(yè)面就好幾個(gè)了丰介,這里就用到了Cookie背蟆,把session id存在Cookie中,每次訪問(wèn)的時(shí)候?qū)ession id帶過(guò)去就可以識(shí)別了.
區(qū)別
- 存儲(chǔ)數(shù)據(jù)量方面:session能夠存儲(chǔ)任意JAVA對(duì)象哮幢,Cookie只能存儲(chǔ)String類型的對(duì)象带膀。
- 一個(gè)在客戶端一個(gè)在服務(wù)端,因?yàn)镃ookie在客戶端橙垢,所以可以編輯偽造垛叨,不是十分安全。
- Session過(guò)多時(shí)會(huì)消耗服務(wù)器資源柜某,大型網(wǎng)站會(huì)有專門(mén)的Session服務(wù)器嗽元,Cookie存在客戶端沒(méi)問(wèn)題。
- 域的支持范圍不一樣喂击,比方說(shuō)a.com的cookie在a.com下都能用剂癌,而www.a.com的session在api.a.com下都不能用,解決這個(gè)問(wèn)題的辦法是JSONP或跨域資源共享翰绊。
session多服務(wù)器間共享
- 服務(wù)器實(shí)現(xiàn)的 session 復(fù)制或 session 共享佩谷,如 webSphere或 JBOSS 在搭集群時(shí)配置實(shí)現(xiàn) session 復(fù)制或 session 共享.致命缺點(diǎn):不好擴(kuò)展和移植。
- 利用成熟技術(shù)做session復(fù)制监嗜,如12306使用的gemfire谐檀,如常見(jiàn)內(nèi)存數(shù)據(jù)庫(kù)redis或memorycache,雖較普適但依賴第三方.
- 將 session維護(hù)在客戶端裁奇,利用 cookie桐猬,但客戶端存在風(fēng)險(xiǎn)數(shù)據(jù)不安全,且可以存放的數(shù)據(jù)量較小框喳,所以將session 維護(hù)在客戶端還要對(duì) session 中的信息加密课幕。
- 第二種方案和第三種方案的合體,可用gemfire實(shí)現(xiàn) session 復(fù)制共享五垮,還可將session 維護(hù)在 redis中實(shí)現(xiàn) session 共享乍惊,同時(shí)可將 session 維護(hù)在客戶端的cookie 中,但前提是數(shù)據(jù)要加密放仗。
這三種方式可迅速切換润绎,而不影響應(yīng)用正常執(zhí)行。在實(shí)踐中,首選 gemfire 或者 redis 作為 session 共享的載體莉撇,一旦 session 不穩(wěn)定出現(xiàn)問(wèn)題的時(shí)候呢蛤,可以緊急切換 cookie 維護(hù) session 作為備用,不影響應(yīng)用提供服務(wù)
單點(diǎn)登錄中棍郎,cookie 被禁用了怎么辦其障?(一點(diǎn)登陸,子網(wǎng)站其他系統(tǒng)不用再登陸)
- 單點(diǎn)登錄的原理是后端生成一個(gè) session ID涂佃,設(shè)置到 cookie励翼,后面所有請(qǐng)求瀏覽器都會(huì)帶上cookie,然后服務(wù)端從cookie獲取 session ID辜荠,查詢到用戶信息汽抚。
- 所以,保持登錄的關(guān)鍵不是cookie伯病,而是通過(guò)cookie 保存和傳輸?shù)?session ID造烁,本質(zhì)是能獲取用戶信息的數(shù)據(jù)。
- 除了cookie午笛,還常用 HTTP 請(qǐng)求頭來(lái)傳輸惭蟋。但這個(gè)請(qǐng)求頭瀏覽器不會(huì)像cookie一樣自動(dòng)攜帶,需手工處理