Session與Cookie的區(qū)別
zhuan(http://www.imtinewlife.com/BBS/ShowPost.asp?ThreadID=2768)
為什么會(huì)有cookie呢,大家都知道,http是無(wú)狀態(tài)的協(xié)議,客戶每次讀取
web頁(yè)面時(shí),服務(wù)器都打開(kāi)新的會(huì)話,而且服務(wù)器也不會(huì)自動(dòng)維護(hù)客戶的上下文信息,那么要怎么才能實(shí)現(xiàn)網(wǎng)上商店中的購(gòu)物車(chē)呢,session就是一種保存
上下文信息的機(jī)制,它是針對(duì)每一個(gè)用戶的,變量的值保存在服務(wù)器端,通過(guò)
SessionID來(lái)區(qū)分不同的客戶,session是以cookie或URL重寫(xiě)為基礎(chǔ)的,默認(rèn)使用cookie來(lái)實(shí)現(xiàn),系統(tǒng)會(huì)創(chuàng)造一個(gè)名為
JSESSIONID的輸出cookie,我們叫做session cookie,以區(qū)別persistent
cookies,也就是我們通常所說(shuō)的cookie,注意session
cookie是存儲(chǔ)于瀏覽器內(nèi)存中的,并不是寫(xiě)到硬盤(pán)上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但
是當(dāng)我們把瀏覽器的cookie禁止后,WEB服務(wù)器會(huì)采用URL重寫(xiě)的方式傳遞Sessionid,我們就可以在地址欄看到sessionid=
KWJHUG6JJM65HS2K6之類(lèi)的字符串。
明白了原理,我們就可以很容易的分辨出persistent cookies和session
cookie的區(qū)別了,網(wǎng)上那些關(guān)于兩者安全性的討論也就一目了然了,session
cookie針對(duì)某一次會(huì)話而言,會(huì)話結(jié)束session cookie也就隨著消失了,而persistent
cookie只是存在于客戶端硬盤(pán)上的一段文本(通常是加密的),而且可能會(huì)遭到cookie欺騙以及針對(duì)cookie的跨站腳本攻擊,自然不如
session cookie安全了。
通常session
cookie是不能跨窗口使用的,當(dāng)你新開(kāi)了一個(gè)瀏覽器窗口進(jìn)入相同頁(yè)面時(shí),系統(tǒng)會(huì)賦予你一個(gè)新的sessionid,這樣我們信息共享的目的就達(dá)不到
了,此時(shí)我們可以先把sessionid保存在persistent
cookie中,然后在新窗口中讀出來(lái),就可以得到上一個(gè)窗口SessionID了,這樣通過(guò)session
cookie和persistent cookie的結(jié)合我們就實(shí)現(xiàn)了跨窗口的session tracking(會(huì)話跟蹤)。
在一些WEB開(kāi)發(fā)的書(shū)中,往往只是簡(jiǎn)單的把Session和cookie作為兩種并列的http傳送信息的方式,session
cookies位于服務(wù)器端,persistent
cookie位于客戶端,可是session又是以cookie為基礎(chǔ)的,明白的兩者之間的聯(lián)系和區(qū)別,我們就不難選擇合適的技術(shù)來(lái)開(kāi)發(fā)WEB
service了。
(1)
session總是放在服務(wù)器上的,每個(gè)客戶會(huì)跟一個(gè)sessionID對(duì)應(yīng)。因?yàn)镠TTP是無(wú)連接的,如何區(qū)分同一個(gè)客戶的多次請(qǐng)求呢,就需要客戶端每次發(fā)請(qǐng)求的時(shí)候,發(fā)送相應(yīng)的sessionID。
通常情況下,sessionID在客戶端以cookie的形式保存。如果瀏覽器靜止了cookie,客戶端再向服務(wù)器發(fā)請(qǐng)求的時(shí)候,就不會(huì)發(fā)送sessionID,因此服務(wù)器就會(huì)將這個(gè)請(qǐng)求作為一個(gè)新客戶,所以就會(huì)出現(xiàn)session值丟失的假象。
這
時(shí)候出現(xiàn)一個(gè)問(wèn)題,如果客戶瀏覽器不支持cookie,怎么辦?J2EE提供的另一個(gè)辦法就是URL重寫(xiě),寫(xiě)超鏈接的時(shí)侯,總是用
response.encodeURL(url),連接就會(huì)變成*.jsp?sessionID=......,完成了原來(lái)用cookie完成的功能。
J2EE建議,不論客戶瀏覽器是否支持cookie,服務(wù)器端編程都建議使用URL重寫(xiě)。
(2)
web上用的都是非連接的網(wǎng)絡(luò)協(xié)議
session 是存在服務(wù)器上的
每個(gè)session有一個(gè)唯一的session ID(為了標(biāo)識(shí)他是那個(gè)客戶端的)
在啟動(dòng)session的同時(shí),會(huì)在客戶端生成cookie,服務(wù)器把session ID加到cookie中
每次服務(wù)器和客戶端交互的時(shí)候,就是從cookie中取得session ID 來(lái)定位服務(wù)器上的session
這樣只要你的cookie不過(guò)期,服務(wù)器上有你的session,就不會(huì)出問(wèn)題
(3)
JSP實(shí)現(xiàn)在瀏覽器關(guān)閉cookies情況下的會(huì)話管理
通常,會(huì)話管理是通過(guò)服務(wù)器將 Session ID 作為一個(gè) cookie 存儲(chǔ)在用戶的 Web 瀏覽器中來(lái)唯一標(biāo)識(shí)每個(gè)用戶會(huì)話。如果瀏覽器不支持 cookies,或者將瀏覽器設(shè)置為不接受 cookies,我們可以通過(guò) URL 重寫(xiě)來(lái)實(shí)現(xiàn)會(huì)話管理。
實(shí)質(zhì)上 URL 重寫(xiě)是通過(guò)向 URL 連接添加參數(shù),并把 session ID 作為值包含在連接中。然而,為使這生效,你需要為你的 servlet 響應(yīng)部分的每個(gè)連接添加 session ID 。
把 session ID 加到一個(gè)連接可以使用一對(duì)方法來(lái)簡(jiǎn)化:response.encodeURL() 使 URL 包含 session
ID,如果你需要使用重定向,可以使用 response.encodeRedirectURL () 來(lái)對(duì) URL 進(jìn)行編碼。
encodeURL () 及 encodeRedirectedURL () 方法首先判斷 cookies 是否被瀏覽器支持;如果支持,則參數(shù) URL 被原樣返回,session ID 將通過(guò) cookies 來(lái)維持。
來(lái)看下面的例子,兩個(gè) JSP 文件:hello1.jsp 和 hello2.jsp,及它們之間的影響。我們?cè)?hello1.jsp
中簡(jiǎn)單的創(chuàng)建一個(gè)會(huì)話,并在 session 中存儲(chǔ)一個(gè)對(duì)象實(shí)例。接著用戶可以點(diǎn)擊頁(yè)面的連接到達(dá) hello2.jsp。在 hello2.jsp
中,我們從 session 中獲取原先放置的對(duì)象并顯示它的內(nèi)容。注意,我們?cè)?hello1.jsp 中調(diào)用了 encodeURL()
方法來(lái)獲得 hello2.jsp 的鏈接,使得在瀏覽器停用 cookies 的情況下,session ID 自動(dòng)添加到
URL,hello2.jsp 仍能得到 session 對(duì)象。
首先在啟用 cookies 的情況下運(yùn)行。然后關(guān)閉對(duì) cookie 的支持,重啟瀏覽器,再運(yùn)行一次。每次你都可以看到會(huì)話管理在起作用,并能在頁(yè)之間傳遞信息。
注意,如果你想讓這個(gè)例子能在關(guān)閉了 cookies 的瀏覽器中工作,你的 JSP 引擎必須支持 URL 重寫(xiě)。
---------------------------------------------------------------------------------------------------------------------------------------
cookie和session機(jī)制區(qū)別與聯(lián)系
具
體來(lái)說(shuō)cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案。同時(shí)我們也看到,由于采用服務(wù)器端保持
狀態(tài)的方案在客戶端也需要保存一個(gè)標(biāo)識(shí),所以session機(jī)制可能需要借助于cookie機(jī)制來(lái)達(dá)到保存標(biāo)識(shí)的目的,但實(shí)際上它還有其他選擇。
cookie
機(jī)制。正統(tǒng)的cookie分發(fā)是通過(guò)擴(kuò)展HTTP協(xié)議來(lái)實(shí)現(xiàn)的,服務(wù)器通過(guò)在HTTP的響應(yīng)頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應(yīng)的
cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則
在后臺(tái)自動(dòng)發(fā)送給服務(wù)器的。瀏覽器檢查所有存儲(chǔ)的cookie,如果某個(gè)cookie所聲明的作用范圍大于等于將要請(qǐng)求的資源所在的位置,則把該
cookie附在請(qǐng)求資源的HTTP請(qǐng)求頭上發(fā)送給服務(wù)器。
cookie的內(nèi)容主要包括:名字,值,過(guò)期時(shí)間,路徑和域。路徑與域一
起構(gòu)成cookie的作用范圍。若不設(shè)置過(guò)期時(shí)間,則表示這個(gè)cookie的生命期為瀏覽器會(huì)話期間,關(guān)閉瀏覽器窗口,cookie就消失。這種生命期為
瀏覽器會(huì)話期的cookie被稱為會(huì)話cookie。會(huì)話cookie一般不存儲(chǔ)在硬盤(pán)上而是保存在內(nèi)存里,當(dāng)然這種行為并不是規(guī)范規(guī)定的。若設(shè)置了過(guò)期
時(shí)間,瀏覽器就會(huì)把cookie保存到硬盤(pán)上,關(guān)閉后再次打開(kāi)瀏覽器,這些cookie仍然有效直到超過(guò)設(shè)定的過(guò)期時(shí)間。存儲(chǔ)在硬盤(pán)上的cookie可以
在不同的瀏覽器進(jìn)程間共享,比如兩個(gè)IE窗口。而對(duì)于保存在內(nèi)存里的cookie,不同的瀏覽器有不同的處理方式
session機(jī)制。session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類(lèi)似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來(lái)保存信息。
當(dāng)
程序需要為某個(gè)客戶端的請(qǐng)求創(chuàng)建一個(gè)session時(shí),服務(wù)器首先檢查這個(gè)客戶端的請(qǐng)求里是否已包含了一個(gè)session標(biāo)識(shí)(稱為
sessionid),如果已包含則說(shuō)明以前已經(jīng)為此客戶端創(chuàng)建過(guò)session,服務(wù)器就按照sessionid把這個(gè)session檢索出來(lái)使用(檢
索不到,會(huì)新建一個(gè)),如果客戶端請(qǐng)求不包含sessionid,則為此客戶端創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的
session id,sessionid的值應(yīng)該是一個(gè)既不會(huì)重復(fù),又不容易被找到規(guī)律以仿造的字符串,這個(gè)session
id將被在本次響應(yīng)中返回給客戶端保存。
保存這個(gè)sessionid的方式可以采用cookie,這樣在交互過(guò)程中瀏覽器可以自動(dòng)的按照
規(guī)則把這個(gè)標(biāo)識(shí)發(fā)揮給服務(wù)器。一般這個(gè)cookie的名字都是類(lèi)似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機(jī)制以便在
cookie被禁止時(shí)仍然能夠把sessionid傳遞回服務(wù)器。
經(jīng)常被使用的一種技術(shù)叫做URL重寫(xiě),就是把session id直接附加在URL路徑的后面。還有一種技術(shù)叫做表單隱藏字段。就是服務(wù)器會(huì)自動(dòng)修改表單,添加一個(gè)隱藏字段,以便在表單提交時(shí)能夠把sessionid傳遞回服務(wù)器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid"
value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
實(shí)際上這種技術(shù)可以簡(jiǎn)單的用對(duì)action應(yīng)用URL重寫(xiě)來(lái)代替。